/// <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 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 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 BasicOcspResp Generate() { //append nonce if we have it if (_nonce != null) { _extensions_generator.AddExtension(new DerObjectIdentifier("1.3.6.1.5.5.7.48.1.2"), false, _nonce); } //set responseExtensions _builder.SetResponseExtensions(_extensions_generator.Generate()); var ocsp_resp = _builder.Generate(_algorithm, _token.GetPrivateKey(), new[] { _token.GetOcspSigningCert() }, DateTime.UtcNow.AddMinutes(5)); return(ocsp_resp); }
private void doTestRsa() { 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 || !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("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."); } 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); BasicOcspResp resp = respGen.Generate("SHA1withRSA", signKP.Private, chain, DateTime.UtcNow); OCSPRespGenerator rGen = new OCSPRespGenerator(); byte[] enc = rGen.Generate(OCSPRespGenerator.Successful, resp).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 = 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 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); } }