/// <param name="issuerCertificate"></param> /// <inheritdoc /> public async Task <X509Certificate[]> GetChain(X509Certificate issuerCertificate) { var dotNetCertificate = new X509Certificate2(issuerCertificate.GetEncoded()); var certificates = await OcspResponderRepository.GetChain(dotNetCertificate); return(certificates.Select(DotNetUtilities.FromX509Certificate).ToArray()); }
/// <summary> /// Gets the <see cref="OcspResp"/> for the <see cref="OcspReq"/> /// </summary> /// <param name="ocspRequest"></param> /// <param name="issuerCertificate"></param> /// <returns></returns> private async Task <OcspResp> GetOcspDefinitiveResponse(OcspReq ocspRequest, X509Certificate issuerCertificate) { var basicResponseGenerator = new BasicOcspRespGenerator( new RespID( await OcspResponderRepository.GetResponderPublicKey(issuerCertificate))); var extensionsGenerator = new X509ExtensionsGenerator(); var nextUpdate = await OcspResponderRepository.GetNextUpdate(); foreach (var request in ocspRequest.GetRequestList()) { var certificateId = request.GetCertID(); var serialNumber = certificateId.SerialNumber; CertificateStatus certificateStatus; CaCompromisedStatus caCompromisedStatus = await OcspResponderRepository.IsCaCompromised(issuerCertificate); if (caCompromisedStatus.IsCompromised) { // See section 2.7 of RFC 6960 certificateStatus = new RevokedStatus(caCompromisedStatus.CompromisedDate.Value.UtcDateTime, (int)RevocationReason.CACompromise); } else { // Se section 2.2 of RFC 6960 if (await OcspResponderRepository.SerialExists(serialNumber, issuerCertificate)) { var status = await OcspResponderRepository.SerialIsRevoked(serialNumber, issuerCertificate); certificateStatus = status.IsRevoked ? new RevokedStatus(status.RevokedInfo.Date.UtcDateTime, (int)status.RevokedInfo.Reason) : CertificateStatus.Good; } else { certificateStatus = new RevokedStatus(new DateTime(1970, 1, 1), CrlReason.CertificateHold); extensionsGenerator.AddExtension(OcspObjectIdentifierExtensions.PkixOcspExtendedRevoke, false, DerNull.Instance.GetDerEncoded()); } } basicResponseGenerator.AddResponse(certificateId, certificateStatus, DateTimeOffset.UtcNow.DateTime, nextUpdate.UtcDateTime, null); } SetNonceExtension(ocspRequest, extensionsGenerator); basicResponseGenerator.SetResponseExtensions(extensionsGenerator.Generate()); // Algorithm that all clients shall accept as defined in section 4.3 of RFC 6960 const string signatureAlgorithm = "sha256WithRSAEncryption"; var basicOcspResponse = basicResponseGenerator.Generate( signatureAlgorithm, await OcspResponderRepository.GetResponderPrivateKey(issuerCertificate), await OcspResponderRepository.GetChain(issuerCertificate), nextUpdate.UtcDateTime); var ocspResponse = OcspResponseGenerator.Generate(OcspRespStatus.Successful, basicOcspResponse); return(ocspResponse); }
/// <inheritdoc /> public async Task <AsymmetricKeyParameter> GetResponderPublicKey(X509Certificate caCertificate) { var dotNetCertificate = new X509Certificate2(caCertificate.GetEncoded()); var privateKey = await OcspResponderRepository.GetResponderPrivateKey(dotNetCertificate); return(DotNetUtilities.GetKeyPair(privateKey).Public); }
/// <summary> /// Retrieves the <see cref="OcspReq"/> from the request /// </summary> /// <param name="httpRequest"><see cref="OcspHttpRequest"/></param> /// <returns><see cref="OcspReqResult"/> containing the <see cref="OcspReq"/></returns> private async Task <OcspReqResult> GetOcspRequest(OcspHttpRequest httpRequest) { // Validates the header of the request if (httpRequest.MediaType != "application/ocsp-request") { return(new OcspReqResult { Status = OcspRespStatus.MalformedRequest, Error = "OCSP requests requires 'application/ocsp-request' media's type on header" }); } // Try to create the ocsp from the http request OcspReq ocspRequest; try { ocspRequest = CreateOcspReqFromHttpRequest(httpRequest); } catch (Exception e) { return(new OcspReqResult { Status = OcspRespStatus.MalformedRequest, Error = $"Error when creating OcspReq from the request. Exception: {e.Message}" }); } // Validates whether the ocsp request have certificate's requests var requests = ocspRequest.GetRequestList(); if (requests == null || requests.Length == 0) { return(new OcspReqResult { Status = OcspRespStatus.MalformedRequest, Error = "Request list is empty" }); } // Valitates whether the requests are of this CA's responsibility X509Certificate issuerCertificate = null; var issuerCerts = (await OcspResponderRepository.GetIssuerCertificates()).ToArray(); var list = ocspRequest.GetRequestList(); for (var i = 0; i < list.Length; i++) { var request = list[i]; var certificateId = request.GetCertID(); var recognizedIssuerCertificate = issuerCerts.SingleOrDefault(issuerCert => certificateId.MatchesIssuer(issuerCert)); if (i == 0) { issuerCertificate = recognizedIssuerCertificate; } if (recognizedIssuerCertificate == null || !Equals(recognizedIssuerCertificate, issuerCertificate)) { return(new OcspReqResult { Status = OcspRespStatus.Unauthorized, Error = "Any certificate is not of this CA's responsibility" }); } issuerCertificate = recognizedIssuerCertificate; } // Validation passed so we return the ocspRequest with success status return(new OcspReqResult { Status = OcspRespStatus.Successful, OcspRequest = ocspRequest, IssuerCertificate = issuerCertificate }); }
/// <inheritdoc /> public async Task <DateTimeOffset> GetNextUpdate() { return(await OcspResponderRepository.GetNextUpdate()); }
/// <inheritdoc /> public async Task <IEnumerable <X509Certificate> > GetIssuerCertificates() { var certificates = await OcspResponderRepository.GetIssuerCertificates(); return(certificates.Select(DotNetUtilities.FromX509Certificate).ToArray()); }
/// <param name="caCertificate"></param> /// <inheritdoc /> public Task <CaCompromisedStatus> IsCaCompromised(X509Certificate caCertificate) { var dotNetCertificate = new X509Certificate2(caCertificate.GetEncoded()); return(OcspResponderRepository.IsCaCompromised(dotNetCertificate)); }
/// <inheritdoc /> public Task <CertificateRevocationStatus> SerialIsRevoked(BigInteger serial, X509Certificate issuerCertificate) { var dotNetCertificate = new X509Certificate2(issuerCertificate.GetEncoded()); return(OcspResponderRepository.SerialIsRevoked(serial.ToString(), dotNetCertificate)); }
/// <inheritdoc /> public Task <bool> SerialExists(BigInteger serial, X509Certificate issuerCertificate) { var dotNetCertificate = new X509Certificate2(issuerCertificate.GetEncoded()); return(OcspResponderRepository.SerialExists(serial.ToString(), dotNetCertificate)); }