示例#1
0
        /// <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 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());
        }
示例#3
0
 public BasicResponseGenerator(IToken token, string signingAlgorithm)
 {
     _token     = token;
     _algorithm = signingAlgorithm;
     _builder   = new BasicOcspRespGenerator(new RespID(_token.GetOcspSigningCert().SubjectDN));
     //_builder = new BasicOcspRespGenerator (issuer.caCertificate.GetPublicKey());
     _extensions_generator = new X509ExtensionsGenerator();
 }
示例#4
0
        /// <exception cref="Org.BouncyCastle.Security.Certificates.CertificateEncodingException"/>
        public TestOcspResponseBuilder(X509Certificate caCert)
        {
            this.caCert = caCert;
            X509Name issuerDN = caCert.IssuerDN;

            thisUpdate      = thisUpdate.AddDays(-1);
            nextUpdate      = nextUpdate.AddDays(30);
            responseBuilder = new BasicOcspRespGenerator(new RespID(issuerDN));
        }
示例#5
0
        public TestOcspResponseBuilder(X509Certificate issuerCert, ICipherParameters issuerPrivateKey)
        {
            this.issuerCert       = issuerCert;
            this.issuerPrivateKey = issuerPrivateKey;
            X509Name subjectDN = issuerCert.SubjectDN;

            thisUpdate      = thisUpdate.AddDays(-1);
            nextUpdate      = nextUpdate.AddDays(30);
            responseBuilder = new BasicOcspRespGenerator(new RespID(subjectDN));
        }
示例#6
0
        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);
        }
示例#7
0
		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();
		}
示例#8
0
        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);
        }
示例#10
0
        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);
            }
        }