Ejemplo n.º 1
0
        /// <summary>
        /// Add nonce extension if it exists in the request
        /// </summary>
        /// <param name="ocspRequest">ocsp request</param>
        /// <param name="extensionsGenerator">extensions generator</param>
        private void SetNonceExtension(OcspReq ocspRequest, X509ExtensionsGenerator extensionsGenerator)
        {
            var nonce = ocspRequest.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce);

            if (nonce != null)
            {
                extensionsGenerator.AddExtension(OcspObjectIdentifiers.PkixOcspNonce, false, nonce.GetOctets());
            }
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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();
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        public static Asn1OctetString ExtractNonce(OcspReq req)
        {
            var nonce_oid = new DerObjectIdentifier("1.3.6.1.5.5.7.48.1.2");

            return(req.GetExtensionValue(nonce_oid));
        }
        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);
        }
Ejemplo n.º 7
0
        private int VerifyOCSPResponse()
        {
            if (ocspResponse.Status != 0)
            {
                this.lastError = Resources.INVALID_OCSP_STATUS + ocspResponse.Status;
                return((int)CertStatus.ERROR);
            }

            BasicOcspResp basicResponse = (BasicOcspResp)ocspResponse.GetResponseObject();

            if (basicResponse != null)
            {
                if (responderCert != null)
                {
                    bool verifyResult = basicResponse.Verify(responderCert.GetPublicKey());

                    if (verifyResult != true)
                    {
                        this.lastError = Resources.OCSP_VERIFY_FAILED;
                        return((int)CertStatus.ERROR);
                    }
                }

                SingleResp[] responses = basicResponse.Responses;

                byte[] reqNonce  = ocspRequest.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce).GetEncoded();
                byte[] respNonce = basicResponse.GetExtensionValue(OcspObjectIdentifiers.PkixOcspNonce).GetEncoded();

                if (reqNonce == null || Arrays.AreEqual(reqNonce, respNonce))
                {
                    // will handle single response only
                    if (responses.Length != 1)
                    {
                        this.lastError = Resources.INVALID_OCSP_RESPONSE_COUNT + responses.Length;
                        return((int)CertStatus.ERROR);
                    }

                    SingleResp resp = responses[0];

                    // Check that response creation time is in valid time slot.
                    DateTime       thisUpdate = resp.ThisUpdate;
                    DateTimeObject nextUpdate = resp.NextUpdate;
                    DateTime       now        = DateTime.UtcNow;

                    // Check whether response creation ramained in valid slot
                    bool valid = CheckTimeValidity(thisUpdate, nextUpdate, 5000, 100000);
                    if (valid == false)
                    {
                        this.lastError = Resources.INVALID_OCSP_TIMESLOT;
                        return((int)CertStatus.ERROR);
                    }

                    Object status = resp.GetCertStatus();

                    if (status == CertificateStatus.Good)
                    {
                        // Ok
                        return((int)CertStatus.GOOD);
                    }
                    else if (status is RevokedStatus)
                    {
                        this.lastError = string.Format(Resources.OCSP_ERROR,
                                                       resp.GetCertID().SerialNumber,
                                                       "revoked");
                        return((int)CertStatus.REVOKED);
                    }
                    else
                    {
                        this.lastError = string.Format(Resources.OCSP_ERROR,
                                                       resp.GetCertID().SerialNumber,
                                                       "unknown");
                        return((int)CertStatus.UNKNOWN);
                    }
                }
            }
            else
            {
                this.lastError = Resources.INVALID_OCSP_RESPONSE;
            }

            // failed
            return((int)CertStatus.ERROR);
        }