예제 #1
0
        /// <summary>
        /// Checks the status of the certificate against an OCSP server.
        /// Updates the internal state with the result.
        /// </summary>
        /// <param name="revocationLookupClient">The OCSP client to use for the request</param>
        /// <returns>Returns the check status</returns>
        public RevocationResponse CheckRevocationStatus(IRevocationLookup revocationLookupClient)
        {
            RevocationResponse response = new RevocationResponse();

            try
            {
                response = revocationLookupClient.CheckCertificate(x509Certificate);

                if (response.Exception == null)
                {
                    if (response.IsValid)
                    {
                        response.RevocationCheckStatus = RevocationCheckStatus.AllChecksPassed;
                    }
                    else
                    {
                        response.RevocationCheckStatus = RevocationCheckStatus.CertificateRevoked;
                    }
                }
                else
                {
                    response.RevocationCheckStatus = RevocationCheckStatus.UnknownIssue;
                }
            }
            catch (Exception e)
            {
                response.Exception             = e;
                response.RevocationCheckStatus = RevocationCheckStatus.UnknownIssue;
            }

            return(response);
        }
예제 #2
0
        /// <summary>
        /// Returns the status of the certificate. In this offline test implementation of the
        /// IRevocationLookup interface, the response can be set in the configuration file
        /// </summary>
        /// <param name="certificate">The certificate to check</param>
        /// <returns>Returns a revocation status</returns>
        public RevocationResponse CheckCertificate(X509Certificate2 certificate)
        {
            RevocationResponse response = new RevocationResponse();

            response.IsValid    = _testConfig.ReturnPositiveResponse;
            response.NextUpdate = DateTime.MaxValue;
            return(response);
        }
예제 #3
0
        public void LookupTestOkayFoces2()
        {
            try
            {
                X509Certificate2 certificate = new X509Certificate2(LookupTest.foces2OkayCertificate, "Test1234");
                Assert.IsNotNull(certificate, "Test certificate was null.");

                CrlLookup          crlLookup = new CrlLookup();
                RevocationResponse response  = crlLookup.CheckCertificate(certificate);
                Assert.IsTrue(response.IsValid);
                Assert.IsNull(response.Exception, "The lookup return an exception.");
                Assert.AreEqual(RevocationCheckStatus.AllChecksPassed, response.RevocationCheckStatus, "Not all check was performed.");
            }
            catch (Exception exception)
            {
                Assert.Fail(exception.ToString());
            }
        }
예제 #4
0
        public void LookupTestRevokedFoces2()
        {
            try
            {
                X509Certificate2 certificate = new X509Certificate2(LookupTest.foces2RevokedCertificate, "Test1234");
                Assert.IsNotNull(certificate, "Test certificate was null.");

                CrlLookup          crlLookup = new CrlLookup();
                RevocationResponse response  = crlLookup.CheckCertificate(certificate);
                Assert.IsNull(response.Exception, "The lookup return an exception.");
                Assert.AreEqual(RevocationCheckStatus.CertificateRevoked, response.RevocationCheckStatus, "The revokation validation did not parse all check");
                Assert.IsFalse(response.IsValid, "The revoked certifikate was valid");
            }
            catch (Exception exception)
            {
                Assert.Fail(exception.ToString());
            }
        }
예제 #5
0
        public void LookupTestRevokedFoces2()
        {
            try
            {
                X509Certificate2 certificate = new X509Certificate2(LookupTest.foces2RevokedCertificate, "Test1234");
                Assert.IsNotNull(certificate, "Test certificate was null.");

                OcspLookup         ocspLookup = this.CreateOcesLookup();
                RevocationResponse response   = ocspLookup.CheckCertificate(certificate);
                Assert.IsFalse(response.IsValid, "Certificate is not valid.");
                Assert.IsNull(response.Exception, "The lookup return an exception.");
                Assert.AreEqual(RevocationCheckStatus.CertificateRevoked, response.RevocationCheckStatus, "Not all check was performed.");
            }
            catch (Exception exception)
            {
                Assert.Fail(exception.ToString());
            }
        }
예제 #6
0
        private void Revocation(X509Certificate2 certificate)
        {
            // Create the OCSP client
            RevocationLookupFactory revocationLookupFactory = new RevocationLookupFactory();
            IRevocationLookup       revocationClient        = revocationLookupFactory.CreateRevocationLookupClient();

            // Check the validity status of the certificate using OCSP
            RevocationResponse revocationResponse = revocationClient.CheckCertificate(certificate);

            // Print out info
            Console.Write("  3. Certificate status returned by RevocationLookup.\n       Is valid: ");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(revocationResponse.IsValid.ToString());
            Console.ForegroundColor = ConsoleColor.White;

            // Make sure the cert was valid
            if (!revocationResponse.IsValid)
            {
                throw new Exception("The certificate returned by RevocationLookup was not valid");
            }
        }
예제 #7
0
        protected void ValidateEndpointCertificate(OcesX509Certificate endpointOcesCertificate)
        {
            RevocationLookupFactory ocspLookupFactory = new RevocationLookupFactory();
            IRevocationLookup       ocspClient        = ocspLookupFactory.CreateRevocationLookupClient();

            RevocationResponse ocspStatus = endpointOcesCertificate.CheckRevocationStatus(ocspClient);

            switch (ocspStatus.RevocationCheckStatus)
            {
            case RevocationCheckStatus.AllChecksPassed:
            {
                // all okay
                break;
            }

            case RevocationCheckStatus.CertificateRevoked:
            {
                throw new Exception("Certificate validation error - CertificateRevoked");
                //break;
            }

            case RevocationCheckStatus.NotChecked:
            {
                throw new Exception("Certificate validation error - NotChecked");
                //break;
            }

            case RevocationCheckStatus.UnknownIssue:
            {
                throw new Exception("Certificate validation error - UnknownIssue");
                // break;
            }

            default:
            {
                throw new Exception("Certificate validation error");
                // break;
            }
            }
        }
예제 #8
0
        /// <summary>
        /// Check if the certificate is revoked against ocsp server
        /// </summary>
        /// <param name="certificate">the certificate to check</param>
        /// <returns>RevocationResponse object to store the result</returns>
        /// <exception cref="CheckCertificateOcspUnexpectedException">This exception is thrown, if an unexpected exception is thrown during the method</exception>
        /// <exception cref="CertificateRevokedTimeoutException">This exception is thrown, if the call to Ocsp server takes longer time than the allowed timeout</exception>
        /// <exception cref="CheckCertificateRevokedUnexpectedException">Thrown if an unexpected error occured</exception>
        private RevocationResponse CheckCertificateRevocation(X509Certificate2 certificate)
        {
            RevocationResponse validityCheck = null;

            try {
                // Checks the certificate
                validityCheck = _lookup.CheckCertificate(certificate);
            } catch (ArgumentNullException) {
                throw;
            } catch (CryptographicUnexpectedOperationException) {
                throw;
            } catch (CryptographicException) {
                throw;
            } catch (ArithmeticException) {
                throw;
            } catch (CheckCertificateOcspUnexpectedException) {
                throw;
            } catch (CertificateRevokedTimeoutException) {
                throw;
            } catch (Exception e) {
                throw new CheckCertificateRevokedUnexpectedException(e);
            }
            return(validityCheck);
        }
예제 #9
0
        public RevocationResponse RevocationResponseOnline(X509Certificate2 serverX509Certificate2, X509Certificate2 issuerX509Certificate2)
        {
            RevocationResponse revocationResponse = new RevocationResponse();

            try
            {
                if (serverX509Certificate2 == null)
                {
                    throw new Exception("Server certificate is null");
                }

                // create BouncyCastle certificates
                //X509CertificateParser certParser = new X509CertificateParser();
                //Org.BouncyCastle.X509.X509Certificate serverX509Certificate = certParser.ReadCertificate(serverX509Certificate2.RawData);

                // 1. Get server url
                List <string> urlList = this.GetAuthorityInformationAccessOcspUrl(serverX509Certificate2);

                if (urlList.Count == 0)
                {
                    throw new Exception("No OCSP url found in ee certificate.");
                }

                // we always validate against the first defined url
                string url = urlList[0];


                revocationResponse = this.RevocationResponseOnline(serverX509Certificate2, issuerX509Certificate2, url);
            }
            catch (Exception e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("OCSP valideringen fejlede.", e);
            }

            return(revocationResponse);
        }
예제 #10
0
        private void TextCertificate()
        {
            string subject = string.Empty;

            /* Production configuration */
            // specifie the subject to test
            // Production certificates valid
            // subject = "CN = NemHandel test service (funktionscertifikat) + SERIALNUMBER = CVR:26769388-FID:1200406941690, O = IT- og Telestyrelsen // CVR:26769388, C = DK";
            //subject = "SERIALNUMBER=CVR:30808460-FID:1320135775022 + CN=TEST FOCES1 (funktionscertifikat), O=DANID A/S // CVR:30808460, C=DK";

            // Production certificates not valid


            /* Test configuration */
            //
            // Test certificates valid
            // subject = "CN = Testendpoint (funktionscertifikat) + SERIALNUMBER = CVR:26769388-FID:1208430425605, O = IT- og Telestyrelsen // CVR:26769388, C = DK";
            //subject = "CN = Testendpoint (funktionscertifikat) + SERIALNUMBER = CVR:26769388-FID:1208430425605, O = IT- og Telestyrelsen // CVR:26769388, C = DK";
            // Test certificates not valid
            //subject = "CN = TU GENEREL FOCES gyldig (funktionscertifikat) + SERIALNUMBER = CVR:30808460-FID:94731315, O = Danid A/S // CVR:30808460, C = DK";
            // subject = "CN=Navision (funktionscertifikat) + OID.2.5.4.5=CVR:23267519-FID:1257424251148, O=TIETGENSKOLEN // CVR:23267519, C=DK";
            //subject = "CN = TEST FOCES1 (funktionscertifikat) + SERIALNUMBER = CVR:30808460-FID:1320135775022, O = DANID A/S // CVR:30808460, C = DK";
            // not valid any more
            //subject = "CN=TU GENEREL FOCES gyldig (funktionscertifikat) + SERIALNUMBER = CVR:30808460-FID:94731315, O = Danid A/S // CVR:30808460, C = DK";
            // subject = "CN=TU GENEREL FOCES gyldig (funktionscertifikat) + SERIALNUMBER=CVR:30808460-FID:94731315, O=Danid A/S // CVR:30808460, C=DK";
            // subject = "CN=FOCES1 (funktionscertifikat) + SERIALNUMBER=CVR:30808460-FID:1255692730737, O=DANID A/S // CVR:30808460, C=DK";
            // subject = "CN=TU GENEREL MOCES gyldig + SERIALNUMBER=CVR:30808460-RID:45490598, O=Danid A/S // CVR:30808460, C=DK";

            subject = "CN = mySupply NemHandel - Foces2 (funktionscertifikat) + SERIALNUMBER = CVR:32433030-FID:27705483, O = mySupply NemHandel // CVR:32433030, C = DK";

            //subject = "SERIALNUMBER=CVR:34051178-FID:56940413 + CN=NemLog-in ADFS Test (funktionscertifikat), O=Digitaliseringsstyrelsen // CVR:34051178, C=DK";

            // Now - retrive the certificate in LDAP, if the certificate is pressen...
            CertificateSubject certificateSubject = new CertificateSubject(subject);
            LdapLookupFactory  ldapClientFactory  = new LdapLookupFactory();
            ICertificateLookup ldapClient         = ldapClientFactory.CreateLdapLookupClient();

            // Lookup the certificate using LDAP
            X509Certificate2 certificate = ldapClient.GetCertificate(certificateSubject);

            if (certificate != null)
            {
                Console.Write("Certificate whith subject ");
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write(subject);
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(" found in LDAP.");

                // Validate that the certificate is valid in OCSP

                RevocationLookupFactory revocationLookupFactory = new RevocationLookupFactory();
                IRevocationLookup       revocationClient        = revocationLookupFactory.CreateRevocationLookupClient();

                // Check the validity status of the certificate using OCSP
                RevocationResponse revocationResponse = revocationClient.CheckCertificate(certificate);
                if (revocationResponse.IsValid)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.Write("Certificate valid in OCSP/CRL");
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("Certificate not valid in OCSP/CRL");
                }
            }
            else
            {
                Console.Write("Certificate whith subject ");
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(subject);
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(" NOT found in LDAP.");
            }

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine();
            Console.WriteLine("Press any key to exit.");
            Console.ReadLine();
        }
예제 #11
0
        //private X509Certificate2 certificateMoces = new X509Certificate2(CrlLookupTest. medarbejdercertifikatRevoked, "Test1234");

        private void ThreadCertificateCheck()
        {
            CrlLookup crlLookup = new CrlLookup();

            for (int i = 0; i < 16; i++)
            {
                Random random = new Random();
                int    select = random.Next(2);
                if (select < 1)
                {
                    Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 allOkay", DateTime.Now, i);

                    RevocationResponse response = crlLookup.CheckCertificate(certificateFoces);
                    if (response.Exception != null)
                    {
                        Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 Exception: " + response.Exception.ToString(), DateTime.Now, i);
                    }

                    if (response.IsValid)
                    {
                        // yes - certificate is valid
                        if (response.RevocationCheckStatus == RevocationCheckStatus.AllChecksPassed)
                        {
                            // yes - check all parsed
                        }
                        else
                        {
                            Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 not all checked parsed ", DateTime.Now, i);
                            Assert.Fail("Foces2 certifiate should have been valid.");
                        }
                    }
                    else
                    {
                        // arg - certificate is not valid
                        Assert.IsTrue(response.IsValid, "Foces certifiate should have been valid.");
                        Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 not all checked parsed ", DateTime.Now, i);
                    }
                }
                else
                {
                    //// moces1
                    //Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 revoked", DateTime.Now, i);

                    //RevocationResponse response = crlLookup.CheckCertificate(certificateMoces);
                    //if (response.Exception != null)
                    //{
                    //    Console.WriteLine("{0} ThreadCertificateCheck number:{1} foces1 Exception: " + response.Exception.ToString(), DateTime.Now, i);
                    //}

                    //if (!response.IsValid)
                    //{
                    //    // yes - certificate is revoked
                    //    if (response.RevocationCheckStatus == RevocationCheckStatus.CertificateRevoked)
                    //    {
                    //        // yes - check all parsed
                    //    }
                    //    else
                    //    {
                    //        Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 RevocationCheckStatus is not revoked as expected.", DateTime.Now, i);
                    //        Assert.Fail("Moces2 RevocationCheckStatus is not revoked as expected");
                    //    }
                    //}
                    //else
                    //{
                    //    // arg - certificate is valid
                    //    Assert.IsFalse(response.IsValid, "Moces certificate should have been revoked.");
                    //    Console.WriteLine("{0} ThreadCertificateCheck number:{1} moces1 certificate is not revoked as expected.", DateTime.Now, i);
                    //}
                }

                Console.WriteLine("{0} ThreadCertificateCheck number:{1} done", DateTime.Now, i);
            }
        }
예제 #12
0
        /// <summary>
        /// Checks a certificate status in a CRL.
        /// </summary>
        /// <param name="certificate">The certificate to check</param>
        /// <returns>The RevocationResponse object that contains the result</returns>
        public RevocationResponse CheckCertificate(X509Certificate2 certificate)
        {
            /*
             * Assumptions:
             * - Certificate has an CRL Distribution Points extension value.
             * - An HTTP distribution point is present.
             */

            // create RevocationResponse and set default values
            RevocationResponse response = new RevocationResponse();

            response.IsValid    = true;
            response.NextUpdate = DateTime.MinValue;

            if (certificate != null)
            {
                X509Chain x509Chain = new X509Chain();
                x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                x509Chain.Build(certificate);

                // Iterate though the chain, to get the certificate list
                X509ChainElementCollection             x509ChainElementCollection = x509Chain.ChainElements;
                X509ChainElementEnumerator             enumerator = x509ChainElementCollection.GetEnumerator();
                X509ChainElement                       x509ChainElement;
                X509Certificate2                       x509Certificate2 = null;
                IDictionary <string, X509Certificate2> map  = new Dictionary <string, X509Certificate2>();
                IList <X509Certificate2>               list = new List <X509Certificate2>();

                while (enumerator.MoveNext())
                {
                    x509ChainElement = enumerator.Current;
                    x509Certificate2 = x509ChainElement.Certificate;
                    list.Add(x509Certificate2);
                }

                // now we have a list of the certificate chain
                // list[0] -> the function certificate
                // list[0 .. lsit.Count] -> middel certificates
                //   oces1 : none middle certificate exist
                //   oces2 : one middle certificate exist
                // list[list.Count] - > root certificate
                // we needed to validate all certificates, except the root certificates
                // The question wheather the root certificates is trusted, is validated in MultipleRootX509CertificateValidator
                // However - In the case where the root certificate is not installed,
                // the chain list will only be 1 length, so no validation is perfored at all.


                int index = 0;
                //bool chainValid = true;
                while (index < (list.Count - 1) && response.IsValid == true)
                {
                    // this.logger.Info("CRL validation the certificate: " + list[index].Subject);
                    // Retrieve URL distribution points
                    List <Uri> URLs = this.GetURLs(list[index]);

                    // The list should only contain one element
                    // so we are only interesting in the first CRL list
                    if (URLs.Count > 0)
                    {
                        Uri         url = URLs[0];
                        CrlInstance crl = this.GetInstance(url);

                        try
                        {
                            if (!crl.IsRevoked(certificate))
                            {
                                // so the certificate is not revoked.
                                // remember, that the issueing certificate could be revoked.
                                // So the next update must be the earlist of the all
                                response.IsValid = true;
                                if (response.NextUpdate == DateTime.MinValue)
                                {
                                    response.NextUpdate = crl.getNextUpdate();
                                }
                                else if (response.NextUpdate < crl.getNextUpdate())
                                {
                                    // no new update
                                    // the already registrated 'NextUpdate' is before the crl.getNextUpdate
                                }
                                else
                                {
                                    // new update time
                                    // The already registrated 'NextUpdate', is greater (futher in the future) then crl.getNextUpdate
                                    // so we use the crl.getNextUpdate as next update
                                    response.NextUpdate = crl.getNextUpdate();
                                }
                            }
                            else
                            {
                                response.IsValid = false;
                            }
                        }
                        catch (CheckCertificateRevokedUnexpectedException exception)
                        {
                            // could not validate the certificate - so i don't trust it
                            response.Exception = exception;
                            response.IsValid   = false;
                        }
                    }
                    else
                    {
                        // url server not identified, so we don't trust this certificate
                        response.IsValid = false;
                    }

                    // increase the index, to check the next certificate
                    index++;
                }

                // all the certificate in the chain is now checked.
                if (response.IsValid == true)
                {
                    response.RevocationCheckStatus = RevocationCheckStatus.AllChecksPassed;
                }
                else
                {
                    response.RevocationCheckStatus = RevocationCheckStatus.CertificateRevoked;
                }

                x509Chain.Reset();
            }
            else
            {
                response.IsValid               = false;
                response.Exception             = new CheckCertificateRevokedUnexpectedException(new Exception("Error during CRL lookup. The certificate is null"));//did not have any CRL DistPoints. Certificate: " + certificate));
                response.RevocationCheckStatus = RevocationCheckStatus.UnknownIssue;
            }

            return(response);
        }
예제 #13
0
        /// <summary>
        /// Checks a certificate, with default rootcertificate.
        /// All fields of the CertificateCheckResult structure are initialized as "false".
        /// Certificate checking may end before all checks have been performed, if individual
        /// checks fail. In that case, only the fields of the CertificateCheckResult structure that
        /// corresponds to checks already performed are valid.
        /// </summary>
        /// <param name="certificate">certificate to check</param>
        /// <param name="rootCertificate">a given rootcertificate</param>
        /// <returns>The object that contains the result. Note that all fields of the CertificateCheckResult
        /// structure are initialized as "false". Certificate checking may end before all checks have
        /// been performed, if individual checks fail. In that case, only the fields of the
        /// CertificateCheckResult structure that
        /// corresponds to checks already performed are valid.</returns>
        public CertificateCheckResult CheckCertificate(X509Certificate2 certificate, X509Certificate2 rootCertificate)
        {
            CertificateCheckResult result = new CertificateCheckResult();

            try {
                //1. that the certificate has the default rootcertificate as root.
                // Also checks that the cert is not expired or not yet activated.
                CheckCertificateChain(certificate, result);

                if (!result.CertificateActivated ||
                    !result.CertificateValid ||
                    !result.RootCertificateAsRoot
                    )
                {
                    result.AllTestsPassed = false;
                    return(result);
                }

                //2. that the rootcertificate is not expired or not activated
                if (rootCertificate == null)
                {
                    CheckRootCertificateValidation(_defaultOCESrootCertificate, result);
                    CheckRootCertificateActivated(_defaultOCESrootCertificate, result);
                }
                else
                {
                    CheckRootCertificateValidation(rootCertificate, result);
                    CheckRootCertificateActivated(rootCertificate, result);
                }

                if (!result.RootCertificateValid || !result.RootCertificateActivated)
                {
                    result.AllTestsPassed = false;
                    return(result);
                }

                //4. check if the certificate is revoked async
                RevocationResponse response = CheckCertificateRevocation(certificate);
                if (!response.IsValid)
                {
                    result.AllTestsPassed     = false;
                    result.CertificateRevoked = true;
                    return(result);
                }

                //5. check certificatetype
                CheckCertificateType(certificate, result);

                if (result.CertificateActivated && !result.CertificateRevoked && result.CertificateValid &&
                    result.RootCertificateActivated && result.RootCertificateAsRoot && result.RootCertificateValid)
                {
                    result.AllTestsPassed = true;
                }
            } catch (ArgumentNullException) {
                throw;
            } catch (OverflowException) {
                throw;
            } catch (FormatException) {
                throw;
            } catch (CryptographicUnexpectedOperationException) {
                throw;
            } catch (CryptographicException) {
                throw;
            } catch (CheckCertificateOcspUnexpectedException) {
                throw;
            } catch (CertificateRevokedTimeoutException) {
                throw;
            } catch (Exception) {
                throw;
            }
            return(result);
        }
예제 #14
0
        /* /// <summary>
         * /// Overrides the method to validate the binding element order.
         * /// </summary>
         * /// <typeparam name="TChannel"></typeparam>
         * /// <param name="context"></param>
         * /// <returns></returns>
         * public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
         * {
         *   BindingElementCollection bindingElements = context.Binding.Elements;
         *   this.stackCheck.Check(bindingElements);
         *   return base.BuildChannelListener<TChannel>(context);
         * }*/

        /// <summary>
        /// Intercept requests and creates the proof of validation interception before
        /// attaching it to the message.
        /// </summary>
        /// <param name="interceptorMessage"></param>
        public override void InterceptRequest(InterceptorMessage interceptorMessage)
        {
            this.logger.Trace("Security validate the foces certificate.");
            try
            {
                Headers headers = new Headers(interceptorMessage);
                if (interceptorMessage.IsFault)
                {
                    // do nothing
                }
                else if (headers.IsCreateSequence)
                {
                    // do nothing
                }
                else if (headers.SequenceHeader == null)
                {
                    // do nothing
                }
                else if (headers.SequenceHeader.IsLastMessage)
                {
                    // do nothing
                }
                else
                {
                    // Get the certificate from the message
                    X509Certificate2 certificate;
                    try
                    {
                        certificate = interceptorMessage.Certificate;
                    }
                    catch
                    {
                        throw new FailedToGetCertificateSubjectException(interceptorMessage);
                    }



                    // now we must revocate check the certificate
                    OcesX509Certificate ocesCertificate = new OcesX509Certificate(certificate);
                    RevocationResponse  response        = ocesCertificate.CheckRevocationStatus(revocationLookup);

                    if (response.Exception != null)
                    {
                        string msg;
                        try
                        {
                            msg = response.Exception.Message;
                        }
                        catch (Exception ex)
                        {
                            this.logger.Debug("Error finding the correct error message.", ex);
                            msg = "unknown";
                        }

                        this.logger.Warn(string.Format("The certificate '{0}' revocation check failed. Reason is: ", ocesCertificate.Certificate.SubjectName.Name, msg));

                        // some error checking the certificate
                        // make sure the error is of the correct type, and throw it
                        // note - if the original exception was not a communikation exception, it is wraped in a communikation exception
                        if (response.Exception is CertificateRevokedTimeoutException)
                        {
                            throw new CertificateRevokedValidationFailedException(response.Exception);
                        }
                        else if (response.Exception is CertificateRevokedException)
                        {
                            throw response.Exception;
                        }
                        else if (response.Exception is CertificateRevokedValidationFailedException)
                        {
                            throw response.Exception;
                        }
                        else if (response.Exception is CheckCertificateOcspUnexpectedException)
                        {
                            throw new CertificateRevokedValidationFailedException(response.Exception);
                        }
                        else if (response.Exception is CheckCertificateRevokedUnexpectedException)
                        {
                            throw new CertificateRevokedValidationFailedException(response.Exception);
                        }
                        else
                        {
                            throw new CertificateRevokedValidationFailedException(response.Exception);
                        }
                    }
                    else
                    {
                        // no exception - all good so far
                        switch (response.RevocationCheckStatus)
                        {
                        case RevocationCheckStatus.AllChecksPassed:
                        {
                            // all good
                            this.logger.Debug(string.Format("Certificate '{0}' has parsed the revocation validate.", certificate.SubjectName.Name));
                            SignatureValidationProof signatureValidationProof = new SignatureValidationProof(certificate.Subject);
                            interceptorMessage.AddProperty(ServerSignatureValidationProofBindingExtensionElement.SignatureValidationProofKey, signatureValidationProof);
                            break;
                        }

                        case RevocationCheckStatus.CertificateRevoked:
                        {
                            this.logger.Warn(string.Format("The certificate '{0}' is revoked.", ocesCertificate.Certificate.SubjectName.Name));
                            throw new CertificateRevokedException();
                            //break;
                        }

                        default:
                        {
                            this.logger.Warn(string.Format("The certificate '{0}' failed in revocation check - reason unknown", ocesCertificate.Certificate.SubjectName.Name));
                            throw new CertificateRevokedValidationFailedException("The certificate failed in revocation check - reason unknown.");
                            //break;
                        }
                        }
                    }
                }
            }
            catch (FailedToGetCertificateSubjectException)
            {
                // exception is of the correct type - rethrowing it
                throw;
            }

            /* catch (CertificateRevokedTimeoutException e)
             * {
             *   // exception is of the correct type - rethrowing it
             *   throw new CertificateRevokedValidationFailedException(e);
             * }*/
            catch (CertificateRevokedException)
            {
                // exception is of the correct type - rethrowing it
                throw;
            }
            catch (CertificateRevokedValidationFailedException)
            {
                // exception is of the correct type - rethrowing it
                throw;
            }

            /*  catch (CheckCertificateOcspUnexpectedException)
             * {
             *    // exception is of the correct type - rethrowing it
             *    throw;
             * }*/
            /* catch (CheckCertificateRevokedUnexpectedException)
             * {
             *   // exception is of the correct type - rethrowing it
             *   throw;
             * }*/
            catch (Exception ex)
            {
                this.logger.Debug("Security validate the foces certificate", ex);
                throw new CertificateRevokedValidationFailedException(ex);
            }

            this.logger.Trace("Security validate the foces certificate - Finish.");
        }
예제 #15
0
        /// <summary>
        /// Checks a certificate status on a ocsp server
        /// </summary>
        /// <param name="x509Certificate2">The certificate to check</param>
        /// <returns>The RevocationResponse object that contains the result</returns>
        /// <exception cref="CheckCertificateOcspUnexpectedException">This exception is thrown, if an unexpected exception is thrown during the method</exception>
        private RevocationResponse RevocationResponseOnline(X509Certificate2 x509Certificate2)
        {
            RevocationResponse revocationResponse = new RevocationResponse();

            if (x509Certificate2 == null)
            {
                throw new CheckCertificateOcspUnexpectedException();
            }
            // http://bouncy-castle.1462172.n4.nabble.com/c-ocsp-verification-td3160243.html
            X509Certificate2 issuerX509Certificate2 = this.FindIssuerCertificate(x509Certificate2);

            if (issuerX509Certificate2 == null)
            {
                throw new CheckCertificateOcspUnexpectedException("Issuer certificate '" + x509Certificate2.Issuer + "' not found.");
            }

            if (issuerX509Certificate2.Thumbprint.Equals(x509Certificate2.Thumbprint, StringComparison.OrdinalIgnoreCase))
            {
                // the certificate and the issuer certificace is the same
                // this mean that the root certificate is not trusted
                revocationResponse = null;
            }
            else
            {
                revocationResponse = this.RevocationResponseOnline(x509Certificate2, issuerX509Certificate2);

                if (revocationResponse != null)
                {
                    if (revocationResponse.Exception == null)
                    {
                        // no exception recorded
                        if (revocationResponse.IsValid)
                        {
                            // now we know the certificate is valid.
                            // if the issuer is a trusted root certificate, all is good
                            if (this.rootCertificateDirectory.ContainsKey(issuerX509Certificate2.Thumbprint.ToLowerInvariant()))
                            {
                                // the root certificate is trusted, so the RevocationResponse can be put on the cache
                                this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse);
                            }
                            else
                            {
                                // we do not yet know if the certificate is valid.
                                // the certificate migth be good, but if the issueing certificate is revoked,
                                // then the certificate should also be revoked.
                                // Validate the issuer certificate
                                // this is required, because certificate can have a chain that is longer then 2

                                // The only problem is, that we can not ocsp validate the intermiddel certificate (the issuer certificate).
                                // acording to DanID - that certificate can only be validated with CRL
                                // Note : The crl list will be/should be very short. Only containing the issuer certificate that has been revoked.
                                //        A good guess is that there at all time will be most 10 issuer certificate, so the list of revoked issuer certificate is short.
                                IList <string>     issuerUrl = this.GetAuthorityInformationAccessOcspUrl(issuerX509Certificate2);
                                RevocationResponse issuerRevocationResponse;

                                if (issuerUrl.Count > 0)
                                {
                                    // hey, wow some url exist - lets use that
                                    // don't thing this will ever happens anyway
                                    issuerRevocationResponse = this.RevocationResponse(issuerX509Certificate2);
                                }
                                else
                                {
                                    // we need to validate with crl instead
                                    // It does not contain the Authority Info Access, containng the rl to where the certificate must be validated
                                    // We must therefore gues, that the certificate is valid.
                                    CrlLookup crlLookupClient = new CrlLookup();
                                    issuerRevocationResponse = crlLookupClient.CheckCertificate(issuerX509Certificate2);
                                }

                                // now to handle the issuerRevocationResponse
                                if (issuerRevocationResponse != null)
                                {
                                    // the issuer certificate is validated, the validity of the issuer certificate
                                    // is copied to the revocationResponse
                                    revocationResponse.IsValid   = issuerRevocationResponse.IsValid;
                                    revocationResponse.Exception = issuerRevocationResponse.Exception;
                                }
                                else
                                {
                                    revocationResponse.IsValid   = false;
                                    revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("The issueing certificate could not be validated.");
                                }

                                // update the cache
                                this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse);
                            }
                        }
                        else
                        {
                            // the certificate is NOT valid
                            // no need to check the issuer certificate
                            this.ocspCache.Set(x509Certificate2.Thumbprint.ToLowerInvariant(), revocationResponse);
                        }
                    }
                    else
                    {
                        // some exception returned.
                        // do not add to cache
                    }
                }
            }

            return(revocationResponse);
        }
예제 #16
0
        private RevocationResponse ProcessOcspResponse(Org.BouncyCastle.X509.X509Certificate serverX509Certificate, Org.BouncyCastle.X509.X509Certificate rootX509Certificate, byte[] binaryResp)
        {
            OcspResp r = new OcspResp(binaryResp);
            //CertificateStatus cStatus = CertificateStatus.Unknown;
            RevocationResponse revocationResponse = new RevocationResponse();

            //X509CertificateParser parser = null;
            //OcspRespStatus.Unauthorized

            switch (r.Status)
            {
            case OcspRespStatus.Successful:
            {
                BasicOcspResp or = (BasicOcspResp)r.GetResponseObject();

                // ValidateResponse(or, issuerCert);

                string certificateSerial = Convert.ToUInt32(serverX509Certificate.SerialNumber.IntValue).ToString();
                bool   found             = false;
                foreach (SingleResp singleResp in or.Responses)
                {
                    if (singleResp.GetCertID().SerialNumber.ToString().Equals(certificateSerial))
                    {
                        found = true;

                        this.ValidateCertificateId(serverX509Certificate, rootX509Certificate, singleResp.GetCertID());

                        // ValidateThisUpdate(resp);
                        // ValidateNextUpdate(resp);

                        Object certificateStatus = singleResp.GetCertStatus();

                        if (certificateStatus == null)
                        {
                            // acording to org.openoces.ooapi.utils.ocsp.ResponseParser.cs (DanID test code)
                            // in the TU11, method SerialNumberInResponseIsNotRevoked(..),
                            // when the certificateStatus is empty, all is okay - not revoked
                            // no revocation data exist - the certificate must be valid
                            revocationResponse.IsValid               = true;
                            revocationResponse.NextUpdate            = singleResp.NextUpdate.Value;
                            revocationResponse.RevocationCheckStatus = RevocationCheckStatus.AllChecksPassed;
                        }
                        else if (certificateStatus == Org.BouncyCastle.Ocsp.CertificateStatus.Good)
                        {
                            // this is the expected certificateStatus for valid certificates
                            // however if the status is good the certificateStatus is null
                            revocationResponse.IsValid               = true;
                            revocationResponse.NextUpdate            = singleResp.NextUpdate.Value;
                            revocationResponse.RevocationCheckStatus = RevocationCheckStatus.AllChecksPassed;
                        }
                        else if (certificateStatus is Org.BouncyCastle.Ocsp.RevokedStatus)
                        {
                            revocationResponse.IsValid               = false;
                            revocationResponse.NextUpdate            = singleResp.NextUpdate.Value;
                            revocationResponse.RevocationCheckStatus = RevocationCheckStatus.CertificateRevoked;
                        }
                        else if (certificateStatus is Org.BouncyCastle.Ocsp.UnknownStatus)
                        {
                            throw new CheckCertificateOcspUnexpectedException("CertificateStatus is Unknown");
                        }
                        else
                        {
                            throw new CheckCertificateOcspUnexpectedException("CertificateStatus is unknown '" + certificateStatus.ToString() + "'.");
                        }

                        // break foreach loop
                        break;
                    }
                }

                if (!found)
                {
                    // the returned result did not contain the desired certificate
                    throw new CheckCertificateOcspUnexpectedException("Revokation result did not contain the desired certificate serial number.");
                }

                break;
            }

            default:
            {
                throw new CheckCertificateOcspUnexpectedException("Unknow status '" + r.Status + "'.");
            }
            }

            return(revocationResponse);
        }
예제 #17
0
        public RevocationResponse RevocationResponseOnline(X509Certificate2 serverX509Certificate2, X509Certificate2 issuerX509Certificate2, string url)
        {
            RevocationResponse revocationResponse = new RevocationResponse();

            try
            {
                if (serverX509Certificate2 == null)
                {
                    throw new Exception("Server certificate is null");
                }

                if (issuerX509Certificate2 == null)
                {
                    throw new Exception("Issuer certificate for server certificate not identified");
                }

                // create BouncyCastle certificates
                X509CertificateParser certParser = new X509CertificateParser();
                Org.BouncyCastle.X509.X509Certificate issuerX509Certificate = certParser.ReadCertificate(issuerX509Certificate2.RawData);
                Org.BouncyCastle.X509.X509Certificate serverX509Certificate = certParser.ReadCertificate(serverX509Certificate2.RawData);

                // 1. Generate request
                OcspReq req = this.GenerateOcspRequest(issuerX509Certificate, serverX509Certificate.SerialNumber);

                // 2. make binary request online
                byte[] encoded    = req.GetEncoded();
                byte[] binaryResp = this.PostData(url, encoded, "application/ocsp-request", "application/ocsp-response");

                //3. check result
                revocationResponse = this.ProcessOcspResponse(serverX509Certificate, issuerX509Certificate, binaryResp);
            }
            catch (CheckCertificateOcspUnexpectedException)
            {
                throw;
            }
            catch (ArgumentNullException e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("ArgumentNullException", e);
            }
            catch (OverflowException e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("OverflowException", e);
            }
            catch (FormatException e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("FormatException", e);
            }
            catch (CryptographicUnexpectedOperationException e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("CryptographicUnexpectedOperationException", e);
            }
            catch (CryptographicException e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("CryptographicException", e);
            }
            catch (Exception e)
            {
                revocationResponse.Exception = new CheckCertificateOcspUnexpectedException("OCSP valideringen fejlede.", e);
            }

            return(revocationResponse);
        }