コード例 #1
0
        private CrlInstance GetInstance(Uri url)
        {
            CrlInstance instance = new CrlInstance(url);

            instance = cache.TryAddValue(url, instance);
            return(instance);
        }
コード例 #2
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);
        }