public virtual byte[] MakeOcspResponse(byte[] requestBytes) { OcspReq ocspRequest = new OcspReq(requestBytes); Req[] requestList = ocspRequest.GetRequestList(); X509Extension extNonce = ocspRequest.RequestExtensions.GetExtension(OcspObjectIdentifiers.PkixOcspNonce); if (extNonce != null) { // TODO ensure X509Extensions responseExtensions = new X509Extensions(new Dictionary <DerObjectIdentifier, X509Extension>() { { OcspObjectIdentifiers.PkixOcspNonce, extNonce } }); responseBuilder.SetResponseExtensions(responseExtensions); } foreach (Req req in requestList) { responseBuilder.AddResponse(req.GetCertID(), certificateStatus, thisUpdate.ToUniversalTime(), nextUpdate.ToUniversalTime(), null); } DateTime time = DateTimeUtil.GetCurrentUtcTime(); BasicOcspResp ocspResponse = responseBuilder.Generate(new Asn1SignatureFactory(SIGN_ALG, (AsymmetricKeyParameter)issuerPrivateKey), new X509Certificate[] { issuerCert }, time); // return new OCSPRespBuilder().build(ocspResult, ocspResponse).getEncoded(); return(ocspResponse.GetEncoded()); }
public static IToken GetTokenForRequest(OcspReq ocsp_req) { //TODO: Leverage RequestUtilities.RespondersMatch method to perform the token comparison Req[] request_list = null; try{ request_list = ocsp_req.GetRequestList(); }catch (System.NullReferenceException) { throw new OcspMalformedRequestException("Unknown error parsing the request :("); } if (request_list.Length <= 0) { throw new OcspMalformedRequestException("Empty request list."); } //get first singleRequest Req first_single_req = request_list[0]; IToken _token_a = GetIssuerForSingleRequest(first_single_req).caToken; //if we got only one single_req just return this issuer if (request_list.Length == 1) { return(_token_a); } //check if request contains requests for different responders foreach (Req single_req in request_list) { IToken _token_b = GetIssuerForSingleRequest(single_req).caToken; if (_token_a != _token_b) { throw new OcspMalformedRequestException("Multiple responderIDs in request!"); } } return(_token_a); }
/// <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); }
public override void Respond(HttpListenerContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var bytes = GetOcspRequest(context); if (bytes == null) { context.Response.StatusCode = 400; return; } var ocspReq = new OcspReq(bytes); var respId = new RespID(CertificateAuthority.Certificate.SubjectDN); var basicOcspRespGenerator = new BasicOcspRespGenerator(respId); var requests = ocspReq.GetRequestList(); var nonce = ocspReq.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce); if (nonce != null) { var extensions = new X509Extensions(new Dictionary <DerObjectIdentifier, X509Extension>() { { OcspObjectIdentifiers.PkixOcspNonce, new X509Extension(critical: false, value: nonce) } }); basicOcspRespGenerator.SetResponseExtensions(extensions); } var now = DateTime.UtcNow; foreach (var request in requests) { var certificateId = request.GetCertID(); var certificateStatus = CertificateAuthority.GetStatus(certificateId); var thisUpdate = _options.ThisUpdate?.UtcDateTime ?? now; var nextUpdate = _options.NextUpdate?.UtcDateTime ?? now.AddSeconds(1); basicOcspRespGenerator.AddResponse(certificateId, certificateStatus, thisUpdate, nextUpdate, singleExtensions: null); } var certificateChain = GetCertificateChain(); var basicOcspResp = basicOcspRespGenerator.Generate("SHA256WITHRSA", CertificateAuthority.KeyPair.Private, certificateChain, now); var ocspRespGenerator = new OCSPRespGenerator(); var ocspResp = ocspRespGenerator.Generate(OCSPRespGenerator.Successful, basicOcspResp); bytes = ocspResp.GetEncoded(); context.Response.ContentType = ResponseContentType; WriteResponseBody(context.Response, bytes); }
public override void PerformTest() { string signDN = "O=Bouncy Castle, C=AU"; AsymmetricCipherKeyPair signKP = OcspTestUtil.MakeKeyPair(); X509Certificate testCert = OcspTestUtil.MakeCertificate(signKP, signDN, signKP, signDN); string origDN = "CN=Eric H. Echidna, [email protected], O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One); // // basic request generation // OcspReqGenerator gen = new OcspReqGenerator(); gen.AddRequest( new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One)); OcspReq req = gen.Generate(); if (req.IsSigned) { Fail("signed but shouldn't be"); } X509Certificate[] certs = req.GetCerts(); if (certs != null) { Fail("null certs expected, but not found"); } Req[] requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } // // request generation with signing // X509Certificate[] chain = new X509Certificate[1]; gen = new OcspReqGenerator(); gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred"))); gen.AddRequest( new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One)); chain[0] = testCert; req = gen.Generate("SHA1withRSA", signKP.Private, chain); if (!req.IsSigned) { Fail("not signed but should be"); } if (!req.Verify(signKP.Public)) { Fail("signature failed to Verify"); } requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } certs = req.GetCerts(); if (certs == null) { Fail("null certs found"); } if (certs.Length != 1 || !testCert.Equals(certs[0])) { Fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.GetEncoded(); OcspReq newReq = new OcspReq(reqEnc); if (!newReq.Verify(signKP.Public)) { Fail("newReq signature failed to Verify"); } // // request generation with signing and nonce // chain = new X509Certificate[1]; gen = new OcspReqGenerator(); IList oids = new ArrayList(); IList values = new ArrayList(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.NextBytes(sampleNonce); gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred"))); oids.Add(OcspObjectIdentifiers.PkixOcspNonce); values.Add(new X509Extension(false, new DerOctetString(new DerOctetString(sampleNonce)))); gen.SetRequestExtensions(new X509Extensions(oids, values)); gen.AddRequest( new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One)); chain[0] = testCert; req = gen.Generate("SHA1withRSA", signKP.Private, chain); if (!req.IsSigned) { Fail("not signed but should be"); } if (!req.Verify(signKP.Public)) { Fail("signature failed to Verify"); } // // extension check. // ISet extOids = req.GetCriticalExtensionOids(); if (extOids.Count != 0) { Fail("wrong number of critical extensions in OCSP request."); } extOids = req.GetNonCriticalExtensionOids(); if (extOids.Count != 1) { Fail("wrong number of non-critical extensions in OCSP request."); } Asn1OctetString extValue = req.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce); Asn1Object extObj = X509ExtensionUtilities.FromExtensionValue(extValue); if (!(extObj is Asn1OctetString)) { Fail("wrong extension type found."); } byte[] compareNonce = ((Asn1OctetString)extObj).GetOctets(); if (!AreEqual(compareNonce, sampleNonce)) { Fail("wrong extension value found."); } // // request list check // requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } // // response parsing - test 1 // OcspResp response = new OcspResp(testResp1); if (response.Status != 0) { Fail("response status not zero."); } BasicOcspResp brep = (BasicOcspResp)response.GetResponseObject(); chain = brep.GetCerts(); if (!brep.Verify(chain[0].GetPublicKey())) { Fail("response 1 failed to Verify."); } // // test 2 // SingleResp[] singleResp = brep.Responses; response = new OcspResp(testResp2); if (response.Status != 0) { Fail("response status not zero."); } brep = (BasicOcspResp)response.GetResponseObject(); chain = brep.GetCerts(); if (!brep.Verify(chain[0].GetPublicKey())) { Fail("response 2 failed to Verify."); } singleResp = brep.Responses; // // simple response generation // OCSPRespGenerator respGen = new OCSPRespGenerator(); OcspResp resp = respGen.Generate(OCSPRespGenerator.Successful, response.GetResponseObject()); if (!resp.GetResponseObject().Equals(response.GetResponseObject())) { Fail("response fails to match"); } doTestECDsa(); doTestRsa(); doTestIrregularVersionReq(); }
private void doTestECDsa() { string signDN = "O=Bouncy Castle, C=AU"; AsymmetricCipherKeyPair signKP = OcspTestUtil.MakeECKeyPair(); X509Certificate testCert = OcspTestUtil.MakeECDsaCertificate(signKP, signDN, signKP, signDN); string origDN = "CN=Eric H. Echidna, [email protected], O=Bouncy Castle, C=AU"; GeneralName origName = new GeneralName(new X509Name(origDN)); // // general id value for our test issuer cert and a serial number. // CertificateID id = new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One); // // basic request generation // OcspReqGenerator gen = new OcspReqGenerator(); gen.AddRequest(id); OcspReq req = gen.Generate(); if (req.IsSigned) { Fail("signed but shouldn't be"); } X509Certificate[] certs = req.GetCerts(); if (certs != null) { Fail("null certs expected, but not found"); } Req[] requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } // // request generation with signing // X509Certificate[] chain = new X509Certificate[1]; gen = new OcspReqGenerator(); gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred"))); gen.AddRequest(new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One)); chain[0] = testCert; req = gen.Generate("SHA1withECDSA", signKP.Private, chain); if (!req.IsSigned) { Fail("not signed but should be"); } if (!req.Verify(signKP.Public)) { Fail("signature failed to Verify"); } requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } certs = req.GetCerts(); if (certs == null) { Fail("null certs found"); } if (certs.Length != 1 || !certs[0].Equals(testCert)) { Fail("incorrect certs found in request"); } // // encoding test // byte[] reqEnc = req.GetEncoded(); OcspReq newReq = new OcspReq(reqEnc); if (!newReq.Verify(signKP.Public)) { Fail("newReq signature failed to Verify"); } // // request generation with signing and nonce // chain = new X509Certificate[1]; gen = new OcspReqGenerator(); IList oids = new ArrayList(); IList values = new ArrayList(); byte[] sampleNonce = new byte[16]; Random rand = new Random(); rand.NextBytes(sampleNonce); gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred"))); oids.Add(OcspObjectIdentifiers.PkixOcspNonce); values.Add(new X509Extension(false, new DerOctetString(new DerOctetString(sampleNonce)))); gen.SetRequestExtensions(new X509Extensions(oids, values)); gen.AddRequest(new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One)); chain[0] = testCert; req = gen.Generate("SHA1withECDSA", signKP.Private, chain); if (!req.IsSigned) { Fail("not signed but should be"); } if (!req.Verify(signKP.Public)) { Fail("signature failed to Verify"); } // // extension check. // ISet extOids = req.GetCriticalExtensionOids(); if (extOids.Count != 0) { Fail("wrong number of critical extensions in OCSP request."); } extOids = req.GetNonCriticalExtensionOids(); if (extOids.Count != 1) { Fail("wrong number of non-critical extensions in OCSP request."); } Asn1OctetString extValue = req.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce); Asn1Encodable extObj = X509ExtensionUtilities.FromExtensionValue(extValue); if (!(extObj is Asn1OctetString)) { Fail("wrong extension type found."); } if (!AreEqual(((Asn1OctetString)extObj).GetOctets(), sampleNonce)) { Fail("wrong extension value found."); } // // request list check // requests = req.GetRequestList(); if (!requests[0].GetCertID().Equals(id)) { Fail("Failed isFor test"); } // // response generation // BasicOcspRespGenerator respGen = new BasicOcspRespGenerator(signKP.Public); respGen.AddResponse(id, CertificateStatus.Good); respGen.Generate("SHA1withECDSA", signKP.Private, chain, DateTime.UtcNow); }
public override void Respond(HttpListenerContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var bytes = GetOcspRequest(context); if (bytes == null) { context.Response.StatusCode = 400; return; } var ocspReq = new OcspReq(bytes); var respId = new RespID(CertificateAuthority.Certificate.SubjectDN); var basicOcspRespGenerator = new BasicOcspRespGenerator(respId); var requests = ocspReq.GetRequestList(); var nonce = ocspReq.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce); if (nonce != null) { var extensions = new X509Extensions(new Dictionary <DerObjectIdentifier, X509Extension>() { { OcspObjectIdentifiers.PkixOcspNonce, new X509Extension(critical: false, value: nonce) } }); basicOcspRespGenerator.SetResponseExtensions(extensions); } var now = DateTimeOffset.UtcNow; foreach (var request in requests) { var certificateId = request.GetCertID(); var certificateStatus = CertificateAuthority.GetStatus(certificateId); var thisUpdate = _options.ThisUpdate ?? now; //On Windows, if the current time is equal (to the second) to a notAfter time (or nextUpdate time), it's considered valid. //But OpenSSL considers it already expired (that the expiry happened when the clock changed to this second) var nextUpdate = _options.NextUpdate ?? now.AddSeconds(2); _responses.AddOrUpdate(certificateId.SerialNumber.ToString(), nextUpdate, (key, currentNextUpdate) => { if (nextUpdate > currentNextUpdate) { return(nextUpdate); } return(currentNextUpdate); }); basicOcspRespGenerator.AddResponse(certificateId, certificateStatus, thisUpdate.UtcDateTime, nextUpdate.UtcDateTime, singleExtensions: null); } var certificateChain = GetCertificateChain(); var basicOcspResp = basicOcspRespGenerator.Generate("SHA256WITHRSA", CertificateAuthority.KeyPair.Private, certificateChain, now.UtcDateTime); var ocspRespGenerator = new OCSPRespGenerator(); var ocspResp = ocspRespGenerator.Generate(OCSPRespGenerator.Successful, basicOcspResp); bytes = ocspResp.GetEncoded(); context.Response.ContentType = ResponseContentType; WriteResponseBody(context.Response, bytes); }
public static OcspResp CreateResponseForRequest(OcspReq ocsp_req) { try{ IToken token = GetTokenForRequest(ocsp_req); BasicResponseGenerator resp_generator = new BasicResponseGenerator(token); //append nonce var nonce = RequestUtilities.ExtractNonce(ocsp_req); if (nonce != null) { resp_generator.SetNonce(nonce); } foreach (Req single_req in ocsp_req.GetRequestList()) { CertificateID cert_id; CA issuer; issuer = GetIssuerForSingleRequest(single_req); cert_id = single_req.GetCertID(); log.Debug("Got request for serial: " + cert_id.SerialNumber.ToString() + " for CA: " + issuer.ToString()); //check for ca compromise flag if (issuer.caCompromised == true) { //return revoked with reason cacompromised resp_generator.AddCaCompromisedResponse(cert_id); } else { if (issuer.SerialExists(cert_id.SerialNumber) == false) { //return unknown, if config.rfc6960 is true the return extended revoke instead if (config.getConfigValue("extendedrevoke") == "yes") { //extended revoke, 1 Jan 1970 and certificateHold resp_generator.AddExtendedRevocationResponse(cert_id); continue; } else { //unknown resp_generator.AddUnknownResponse(cert_id); continue; } } //serial exists, check for revocation var crl_entry = issuer.GetCrlEntry(cert_id.SerialNumber); if (crl_entry != null) { //serial is revoked resp_generator.AddRevokedResponse(cert_id, crl_entry); continue; } else { //serial is good resp_generator.AddGoodResponse(cert_id); continue; } } } //Build basic resp BasicOcspResp basic_ocsp_resp = resp_generator.Generate(); OCSPRespGenerator ocsp_resp_builder = new OCSPRespGenerator(); return(ocsp_resp_builder.Generate(OcspRespStatus.Successful, basic_ocsp_resp)); }catch (OcspMalformedRequestException e) { log.Warn(e.Message); return(new OCSPRespGenerator().Generate(OcspRespStatus.MalformedRequest, null)); }catch (OcspUnrecognizedIssuerException e) { log.Warn(e.Message); return(new OCSPRespGenerator().Generate(OcspRespStatus.Unauthorized, null)); } }