public byte[] GetOcspResponse(RevocationStatus status, X509Certificate2 ocspResponder = null, bool includeResponderCertificateInResponse = true) { if (status == RevocationStatus.Unknown) { return(new byte[0]); } if (ocspResponder == null) { ocspResponder = Issuer; } if (Issuer == null) { return(new byte[0]); } var issuerCert = DotNetUtilities.FromX509Certificate(Issuer); var responderCert = DotNetUtilities.FromX509Certificate(ocspResponder); var gen = new OCSPRespGenerator(); var basicGen = new BasicOcspRespGenerator(responderCert.GetPublicKey()); basicGen.AddResponse(new CertificateID(CertificateID.HashSha1, issuerCert, SerialNumber), status == RevocationStatus.Revoked ? new RevokedStatus(DateTime.UtcNow, CrlReason.CessationOfOperation) : CertificateStatus.Good); var certificates = includeResponderCertificateInResponse ? new[] { responderCert } : new X509Certificate[0]; var response = basicGen.Generate(basicGen.SignatureAlgNames.Cast <string>().First(), DotNetUtilities.GetKeyPair(ocspResponder.PrivateKey).Private, certificates, DateTime.UtcNow); var actualResponse = gen.Generate(0, response); return(actualResponse.GetEncoded()); }
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(); }
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(); }
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)); } }
public override void handlePOSTRequest(HttpProcessor p, MemoryStream ms) { try { byte[] ocspdata = ms.ToArray(); OcspReq req = new OcspReq(ocspdata); GeneralName name = req.RequestorName; if (validator != null) { string stat = "GOOD"; foreach (CertificateID id in req.GetIDs()) { Stopwatch st = new Stopwatch(); st.Start(); OCSPCache cac = GetCache(id.SerialNumber.LongValue); if (cac != null) { Console.Write("[CACHED] "); string header = GetRFC822Date(cac.CacheTime); byte[] responseBytes = cac.data; p.outputStream.WriteLine("HTTP/1.1 200 OK"); p.outputStream.WriteLine("content-transfer-encoding: binary"); p.outputStream.WriteLine("Last-Modified: " + header); p.outputStream.WriteLine("Content-Type: application/ocsp-response"); p.outputStream.WriteLine("Connection: keep-alive"); p.outputStream.WriteLine("Accept-Ranges: bytes"); p.outputStream.WriteLine("Server: AS-OCSP-1.0"); p.outputStream.WriteLine("Content-Length: " + responseBytes.Length.ToString()); p.outputStream.WriteLine(""); p.outputStream.WriteContent(responseBytes); } else { // validate OCSPRespGenerator gen = new OCSPRespGenerator(); BasicOcspRespGenerator resp = new BasicOcspRespGenerator(validator.CACert.GetPublicKey()); DerGeneralizedTime dt = new DerGeneralizedTime(DateTime.Parse("03/09/2014 14:00:00")); CrlReason reason = new CrlReason(CrlReason.CACompromise); if (validator.IsRevoked(id, ref dt, ref reason)) { RevokedInfo rinfo = new RevokedInfo(dt, reason); RevokedStatus rstatus = new RevokedStatus(rinfo); resp.AddResponse(id, rstatus); stat = "REVOKED"; } else { resp.AddResponse(id, CertificateStatus.Good); } BasicOcspResp response = resp.Generate("SHA1withRSA", validator.CAKey, new X509Certificate[] { validator.CACert }, DateTime.Now); OcspResp or = gen.Generate(OCSPRespGenerator.Successful, response); string header = GetRFC822Date(DateTime.Now); byte[] responseBytes = or.GetEncoded(); AddCache(responseBytes, id.SerialNumber.LongValue); p.outputStream.WriteLine("HTTP/1.1 200 OK"); p.outputStream.WriteLine("content-transfer-encoding: binary"); p.outputStream.WriteLine("Last-Modified: " + header); p.outputStream.WriteLine("Content-Type: application/ocsp-response"); p.outputStream.WriteLine("Connection: keep-alive"); p.outputStream.WriteLine("Accept-Ranges: bytes"); p.outputStream.WriteLine("Server: AS-OCSP-1.0"); p.outputStream.WriteLine("Content-Length: " + responseBytes.Length.ToString()); p.outputStream.WriteLine(""); p.outputStream.WriteContent(responseBytes); } Console.Write(id.SerialNumber + " PROCESSED IN " + st.Elapsed + " STATUS " + stat); Console.WriteLine(""); } } else { p.writeFailure(); } } catch (Exception ex) { Console.WriteLine("OCSP Server Error : " + ex.Message); } }