Beispiel #1
0
        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());
        }
Beispiel #2
0
        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);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
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();
        }
Beispiel #6
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);
        }
        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);
        }
Beispiel #8
0
 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));
     }
 }