예제 #1
0
        public X509Certificate2 FindIssuerCertificate(X509Certificate2 serverX509Certificate2)
        {
            X509Certificate2 issuerX509Certificate2 = null;

            // Find the issuer certificate
            X509Chain x509Chain = new X509Chain();

            x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            x509Chain.Build(serverX509Certificate2);

            // Iterate though the chain, to validate if it contain a valid root vertificate
            X509ChainElementCollection             x509ChainElementCollection = x509Chain.ChainElements;
            X509ChainElementEnumerator             enumerator = x509ChainElementCollection.GetEnumerator();
            X509ChainElement                       x509ChainElement;
            X509Certificate2                       x509Certificate2 = null;
            IDictionary <string, X509Certificate2> map = new Dictionary <string, X509Certificate2>();

            // At this point, the certificate is not valid, until a
            // it is proved that it has a valid root certificate
            while (enumerator.MoveNext())
            {
                x509ChainElement = enumerator.Current;
                x509Certificate2 = x509ChainElement.Certificate;
                map.Add(x509Certificate2.Subject, x509Certificate2);
            }

            if (map.ContainsKey(serverX509Certificate2.Issuer))
            {
                issuerX509Certificate2 = map[serverX509Certificate2.Issuer];
            }

            return(issuerX509Certificate2);
        }
예제 #2
0
        /// <summary>
        /// Insert the certificate in the certificate list and check the certificate validity.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="unsignedProperties"></param>
        /// <param name="addCert"></param>
        /// <param name="ocspServers"></param>
        /// <param name="crlList"></param>
        /// <param name="digestMethod"></param>
        /// <param name="addCertificateOcspUrl"></param>
        /// <param name="extraCerts"></param>
        /// <param name="useNonce">If true then nonce will be used. The ocsp server should support this. OCSP reposnder in Microsoft Windows must be configured explicitly to support nonce.</param>
        private void AddCertificate(X509Certificate2 cert, UnsignedProperties unsignedProperties, bool addCert, IEnumerable <OcspServer> ocspServers,
                                    IEnumerable <X509Crl> crlList, FirmaXadesNet.Crypto.DigestMethod digestMethod, bool addCertificateOcspUrl, X509Certificate2[] extraCerts = null, bool useNonce = true)
        {
            if (addCert)
            {
                if (CertificateChecked(cert, unsignedProperties))
                {
                    return;
                }

                string guidCert = Guid.NewGuid().ToString();

                Cert chainCert = new Cert();
                chainCert.IssuerSerial.X509IssuerName   = cert.IssuerName.Name;
                chainCert.IssuerSerial.X509SerialNumber = cert.GetSerialNumberAsDecimalString();
                DigestUtil.SetCertDigest(cert.GetRawCertData(), digestMethod, chainCert.CertDigest);
                chainCert.URI = "#Cert" + guidCert;
                unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection.Add(chainCert);

                EncapsulatedX509Certificate encapsulatedX509Certificate = new EncapsulatedX509Certificate
                {
                    Id      = "Cert" + guidCert,
                    PkiData = cert.GetRawCertData()
                };
                unsignedProperties.UnsignedSignatureProperties.CertificateValues.EncapsulatedX509CertificateCollection.Add(encapsulatedX509Certificate);
            }

            var chain = CertUtil.GetCertChain(cert, extraCerts).ChainElements;

            if (chain.Count > 1)
            {
                X509ChainElementEnumerator enumerator = chain.GetEnumerator();
                enumerator.MoveNext(); // el mismo certificado que el pasado por parametro

                enumerator.MoveNext();

                bool valid = ValidateCertificateByCRL(unsignedProperties, cert, enumerator.Current.Certificate, crlList, digestMethod);

                if (!valid)
                {
                    var ocspCerts = ValidateCertificateByOCSP(unsignedProperties, cert, enumerator.Current.Certificate, ocspServers, digestMethod, addCertificateOcspUrl, useNonce);

                    if (ocspCerts != null)
                    {
                        X509Certificate2 startOcspCert = DetermineStartCert(ocspCerts);

                        if (!EquivalentDN(startOcspCert.IssuerName, enumerator.Current.Certificate.SubjectName))
                        {
                            var chainOcsp = CertUtil.GetCertChain(startOcspCert, ocspCerts);

                            AddCertificate(chainOcsp.ChainElements[1].Certificate, unsignedProperties, true, ocspServers, crlList, digestMethod, addCertificateOcspUrl, ocspCerts);
                        }
                    }
                }

                AddCertificate(enumerator.Current.Certificate, unsignedProperties, true, ocspServers, crlList, digestMethod, addCertificateOcspUrl, extraCerts);
            }
        }
예제 #3
0
        /// <summary>
        /// Inserta en la lista de certificados el certificado y comprueba la valided del certificado.
        /// </summary>
        /// <param name="cert"></param>
        /// <param name="unsignedProperties"></param>
        /// <param name="addCertValue"></param>
        /// <param name="extraCerts"></param>
        private void AddCertificate(X509Certificate2 cert, UnsignedProperties unsignedProperties, bool addCert, X509Certificate2[] extraCerts = null)
        {
            if (addCert)
            {
                if (CertificateChecked(cert, unsignedProperties))
                {
                    return;
                }

                string guidCert = Guid.NewGuid().ToString();

                Cert chainCert = new Cert();
                chainCert.IssuerSerial.X509IssuerName   = cert.IssuerName.Name;
                chainCert.IssuerSerial.X509SerialNumber = CertUtil.HexToDecimal(cert.SerialNumber);
                DigestUtil.SetCertDigest(cert.GetRawCertData(), _firma.RefsDigestMethod, chainCert.CertDigest);
                chainCert.URI = "#Cert" + guidCert;
                unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection.Add(chainCert);

                EncapsulatedX509Certificate encapsulatedX509Certificate = new EncapsulatedX509Certificate();
                encapsulatedX509Certificate.Id      = "Cert" + guidCert;
                encapsulatedX509Certificate.PkiData = cert.GetRawCertData();
                unsignedProperties.UnsignedSignatureProperties.CertificateValues.EncapsulatedX509CertificateCollection.Add(encapsulatedX509Certificate);
            }

            var chain = CertUtil.GetCertChain(cert, extraCerts).ChainElements;

            if (chain.Count > 1)
            {
                X509ChainElementEnumerator enumerator = chain.GetEnumerator();
                enumerator.MoveNext(); // el mismo certificado que el pasado por parametro

                enumerator.MoveNext();

                bool valid = ValidateCertificateByCRL(unsignedProperties, cert, enumerator.Current.Certificate);

                if (!valid)
                {
                    var ocspCerts = ValidateCertificateByOCSP(unsignedProperties, cert, enumerator.Current.Certificate);

                    if (ocspCerts != null)
                    {
                        X509Certificate2 startOcspCert = DetermineStartCert(new List <X509Certificate2>(ocspCerts));

                        if (startOcspCert.IssuerName.Name != enumerator.Current.Certificate.SubjectName.Name)
                        {
                            var chainOcsp = CertUtil.GetCertChain(startOcspCert, ocspCerts);

                            AddCertificate(chainOcsp.ChainElements[1].Certificate, unsignedProperties, true, ocspCerts);
                        }
                    }
                }

                AddCertificate(enumerator.Current.Certificate, unsignedProperties, true, extraCerts);
            }
        }
예제 #4
0
        private void TestOCSP()
        {
            OcspLookup ocspLookup = new OcspLookup();

            X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            certStore.Open(OpenFlags.ReadOnly);

            string serial = "4c 05 5a 37";

            X509Certificate2Collection collection = certStore.Certificates.Find(X509FindType.FindBySerialNumber, serial, true);
            X509Certificate2           cert       = null;

            if (collection.Count > 0)
            {
                cert = collection[0];
            }
            else
            {
                // the certificate not found
                throw new NotImplementedException("The certificate was not found.");
            }

            X509Chain x509Chain = new X509Chain();

            x509Chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            x509Chain.Build(cert);

            // Iterate though the chain, to validate if it contain a valid root vertificate
            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>();

            // At this point, the certificate is not valid, until a
            // it is proved that it has a valid root certificate
            while (enumerator.MoveNext())
            {
                x509ChainElement = enumerator.Current;
                x509Certificate2 = x509ChainElement.Certificate;
                list.Add(x509Certificate2);
            }



            ocspLookup.RevocationResponseOnline(list[0], list[1], "http://ocsp.systemtest8.trust2408.com/responder");
        }
        public KeyInfoX509Data(X509Certificate cert, X509IncludeOption includeOption)
        {
            if (cert == null)
            {
                throw new ArgumentNullException("cert");
            }
            X509Certificate2           certificate   = new X509Certificate2(cert);
            X509ChainElementCollection chainElements = null;
            X509Chain chain = null;

            switch (includeOption)
            {
            case X509IncludeOption.ExcludeRoot:
                chain = new X509Chain();
                chain.Build(certificate);
                if ((chain.ChainStatus.Length > 0) && ((chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) == X509ChainStatusFlags.PartialChain))
                {
                    throw new CryptographicException(-2146762486);
                }
                chainElements = chain.ChainElements;
                for (int i = 0; i < (System.Security.Cryptography.X509Certificates.X509Utils.IsSelfSigned(chain) ? 1 : (chainElements.Count - 1)); i++)
                {
                    this.AddCertificate(chainElements[i].Certificate);
                }
                return;

            case X509IncludeOption.EndCertOnly:
                this.AddCertificate(certificate);
                return;

            case X509IncludeOption.WholeChain:
            {
                chain = new X509Chain();
                chain.Build(certificate);
                if ((chain.ChainStatus.Length > 0) && ((chain.ChainStatus[0].Status & X509ChainStatusFlags.PartialChain) == X509ChainStatusFlags.PartialChain))
                {
                    throw new CryptographicException(-2146762486);
                }
                X509ChainElementEnumerator enumerator = chain.ChainElements.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    X509ChainElement current = enumerator.Current;
                    this.AddCertificate(current.Certificate);
                }
                return;
            }
            }
        }
예제 #6
0
 internal static void LogVerifyX509Chain(SignedXml signedXml, X509Chain chain, X509Certificate certificate)
 {
     if (InformationLoggingEnabled)
     {
         string data = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_BuildX509Chain"), new object[] { GetKeyName(certificate) });
         WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, data);
     }
     if (VerboseLoggingEnabled)
     {
         string str2 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_RevocationMode"), new object[] { chain.ChainPolicy.RevocationFlag });
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, str2);
         string str3 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_RevocationFlag"), new object[] { chain.ChainPolicy.RevocationFlag });
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, str3);
         string str4 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_VerificationFlag"), new object[] { chain.ChainPolicy.VerificationFlags });
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, str4);
         string str5 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_VerificationTime"), new object[] { chain.ChainPolicy.VerificationTime });
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, str5);
         string str6 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_UrlTimeout"), new object[] { chain.ChainPolicy.UrlRetrievalTimeout });
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, str6);
     }
     if (InformationLoggingEnabled)
     {
         foreach (X509ChainStatus status in chain.ChainStatus)
         {
             if (status.Status != X509ChainStatusFlags.NoError)
             {
                 string str7 = string.Format(CultureInfo.InvariantCulture, SecurityResources.GetResourceString("Log_X509ChainError"), new object[] { status.Status, status.StatusInformation });
                 WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.X509Verification, str7);
             }
         }
     }
     if (VerboseLoggingEnabled)
     {
         StringBuilder builder = new StringBuilder();
         builder.Append(SecurityResources.GetResourceString("Log_CertificateChain"));
         X509ChainElementEnumerator enumerator = chain.ChainElements.GetEnumerator();
         while (enumerator.MoveNext())
         {
             X509ChainElement current = enumerator.Current;
             builder.AppendFormat(CultureInfo.InvariantCulture, " {0}", new object[] { GetKeyName(current.Certificate) });
         }
         WriteLine(signedXml, TraceEventType.Verbose, SignedXmlDebugEvent.X509Verification, builder.ToString());
     }
 }
예제 #7
0
        private void AddCertificate(X509Certificate2 cert, UnsignedProperties unsignedProperties, bool addCert, IEnumerable <string> ocspServers, IEnumerable <X509Crl> crlList, FirmaXades.Crypto.DigestMethod digestMethod, X509Certificate2[] extraCerts = null)
        {
            if (addCert)
            {
                if (CertificateChecked(cert, unsignedProperties))
                {
                    return;
                }
                string str   = Guid.NewGuid().ToString();
                Cert   cert2 = new Cert();
                cert2.IssuerSerial.X509IssuerName   = cert.IssuerName.Name;
                cert2.IssuerSerial.X509SerialNumber = cert.GetSerialNumberAsDecimalString();
                DigestUtil.SetCertDigest(cert.GetRawCertData(), digestMethod, cert2.CertDigest);
                cert2.URI = "#Cert" + str;
                unsignedProperties.UnsignedSignatureProperties.CompleteCertificateRefs.CertRefs.CertCollection.Add(cert2);
                EncapsulatedX509Certificate encapsulatedX509Certificate = new EncapsulatedX509Certificate();
                encapsulatedX509Certificate.Id      = "Cert" + str;
                encapsulatedX509Certificate.PkiData = cert.GetRawCertData();
                unsignedProperties.UnsignedSignatureProperties.CertificateValues.EncapsulatedX509CertificateCollection.Add(encapsulatedX509Certificate);
            }
            X509ChainElementCollection chainElements = CertUtil.GetCertChain(cert, extraCerts).ChainElements;

            if (chainElements.Count > 1)
            {
                X509ChainElementEnumerator enumerator = chainElements.GetEnumerator();
                enumerator.MoveNext();
                enumerator.MoveNext();
                if (!ValidateCertificateByCRL(unsignedProperties, cert, enumerator.Current.Certificate, crlList, digestMethod))
                {
                    X509Certificate2[] array = ValidateCertificateByOCSP(unsignedProperties, cert, enumerator.Current.Certificate, ocspServers, digestMethod);
                    if (array != null)
                    {
                        X509Certificate2 x509Certificate = DetermineStartCert(new List <X509Certificate2>(array));
                        if (x509Certificate.IssuerName.Name != enumerator.Current.Certificate.SubjectName.Name)
                        {
                            X509Chain certChain = CertUtil.GetCertChain(x509Certificate, array);
                            AddCertificate(certChain.ChainElements[1].Certificate, unsignedProperties, true, ocspServers, crlList, digestMethod, array);
                        }
                    }
                }
                AddCertificate(enumerator.Current.Certificate, unsignedProperties, true, ocspServers, crlList, digestMethod, extraCerts);
            }
        }
예제 #8
0
    private static bool OnValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        SslStream stream = (SslStream)sender;
        SslStreamValidationContext context = s_streamValidationContexts[stream];
        SslSocket     socket = context.m_socket;
        List <string> commonNamesFromCertSubject = GetCommonNamesFromCertSubject(certificate.Subject);
        bool          flag = false;

        if ((socket.m_bundleInfo != null) && socket.m_bundleInfo.isUsingCertBundle)
        {
            byte[] certBundleBytes = socket.m_bundleInfo.certBundleBytes;
            if (socket.m_bundleInfo.isCertBundleSigned)
            {
                if (!VerifyBundleSignature(socket.m_bundleInfo.certBundleBytes))
                {
                    return(false);
                }
                certBundleBytes = GetUnsignedBundleBytes(socket.m_bundleInfo.certBundleBytes);
            }
            byte[] publicKey = certificate.GetPublicKey();
            foreach (string str in commonNamesFromCertSubject)
            {
                if (IsWhitelistedInCertBundle(certBundleBytes, str, publicKey))
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                return(false);
            }
        }
        bool flag3 = IsCertSignedByBlizzard(certificate);
        bool flag4 = false;

        flag4 = true;
        bool flag5 = (!flag3 && flag4) && (chain.ChainElements.Count == 1);

        try
        {
            if (sslPolicyErrors != SslPolicyErrors.None)
            {
                SslPolicyErrors errors = (!flag3 && !flag5) ? SslPolicyErrors.None : (SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNotAvailable);
                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None)
                {
                    string resolvedAddress = socket.m_resolvedAddress;
                    foreach (string str3 in commonNamesFromCertSubject)
                    {
                        if (str3.Equals(resolvedAddress))
                        {
                            errors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                            break;
                        }
                    }
                }
                if ((sslPolicyErrors & ~errors) != SslPolicyErrors.None)
                {
                    object[] args = new object[] { sslPolicyErrors };
                    s_log.LogWarning("Failed policy check. {0}", args);
                    return(false);
                }
            }
            if (chain.ChainElements == null)
            {
                s_log.LogWarning("ChainElements is null");
                return(false);
            }
            X509ChainElementEnumerator enumerator = chain.ChainElements.GetEnumerator();
            while (enumerator.MoveNext())
            {
                X509ChainElement current   = enumerator.Current;
                object[]         objArray2 = new object[] { current.Certificate.Thumbprint };
                s_log.LogDebug("Certificate Thumbprint: {0}", objArray2);
                foreach (X509ChainStatus status in current.ChainElementStatus)
                {
                    object[] objArray3 = new object[] { status.Status };
                    s_log.LogDebug("  Certificate Status: {0}", objArray3);
                }
            }
            bool flag6 = false;
            if (flag3 && (chain.ChainElements.Count == 1))
            {
                chain.ChainPolicy.ExtraStore.Add(s_rootCertificate);
                chain.Build(new X509Certificate2(certificate));
                flag6 = true;
            }
            int num2 = !flag3 ? 3 : 2;
            if (flag4 && !flag6)
            {
                num2 = 1;
            }
            if (chain.ChainElements.Count != num2)
            {
                object[] objArray4 = new object[] { chain.ChainElements.Count };
                s_log.LogWarning("ChainElements.Count is {0}", objArray4);
                return(false);
            }
            for (int i = 0; i < num2; i++)
            {
                if (chain.ChainElements[i] == null)
                {
                    s_log.LogWarning("ChainElements[" + i + "] is null");
                    return(false);
                }
            }
            if (flag3)
            {
                string str4;
                if (ApplicationMgr.GetMobileEnvironment() == MobileEnv.PRODUCTION)
                {
                    str4 = "673D9D1072B625CAD95CB47BF0F0F512233E39FD";
                }
                else
                {
                    str4 = "C0805E3CF51F1A56CE9E6E35CB4F4901B68128B7";
                }
                if (chain.ChainElements[1].Certificate.Thumbprint != str4)
                {
                    s_log.LogWarning("Root certificate thumb print check failure");
                    object[] objArray5 = new object[] { str4 };
                    s_log.LogWarning("  expected: {0}", objArray5);
                    object[] objArray6 = new object[] { chain.ChainElements[1].Certificate.Thumbprint };
                    s_log.LogWarning("  received: {0}", objArray6);
                    return(false);
                }
            }
            for (int j = 0; j < num2; j++)
            {
                if (DateTime.Now > chain.ChainElements[j].Certificate.NotAfter)
                {
                    s_log.LogWarning("ChainElements[" + j + "] certificate is expired.");
                    return(false);
                }
            }
            X509ChainElementEnumerator enumerator4 = chain.ChainElements.GetEnumerator();
            while (enumerator4.MoveNext())
            {
                foreach (X509ChainStatus status2 in enumerator4.Current.ChainElementStatus)
                {
                    if ((!flag3 && !flag6) || (status2.Status != X509ChainStatusFlags.UntrustedRoot))
                    {
                        object[] objArray7 = new object[] { status2.Status };
                        s_log.LogWarning("Found unexpected chain error={0}.", objArray7);
                        return(false);
                    }
                }
            }
        }
        catch (Exception exception)
        {
            object[] objArray8 = new object[] { exception };
            s_log.LogWarning("Exception while trying to validate certificate. {0}", objArray8);
            return(false);
        }
        return(true);
    }
예제 #9
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);
        }
        private static SslSocket.CertValidationResult IsServerCertificateValid(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            SslSocket.CertValidationResult certValidationResult;
            string                str;
            SslStream             sslStream       = (SslStream)sender;
            SslSocket             mSslSocket      = SslSocket.s_streamValidationContexts[sslStream].m_sslSocket;
            SslCertBundleSettings mBundleSettings = mSslSocket.m_bundleSettings;

            if (mBundleSettings.bundle == null || !mBundleSettings.bundle.IsUsingCertBundle)
            {
                return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
            }
            List <string> commonNamesFromCertSubject = SslSocket.GetCommonNamesFromCertSubject(certificate.Subject);

            SslSocket.BundleInfo bundleInfo = new SslSocket.BundleInfo();
            byte[] certBundleBytes          = mBundleSettings.bundle.CertBundleBytes;
            if (mBundleSettings.bundle.isCertBundleSigned)
            {
                if (!SslSocket.VerifyBundleSignature(mBundleSettings.bundle.CertBundleBytes))
                {
                    return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
                }
                certBundleBytes = SslSocket.GetUnsignedBundleBytes(mBundleSettings.bundle.CertBundleBytes);
            }
            if (!SslSocket.GetBundleInfo(certBundleBytes, out bundleInfo))
            {
                return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
            }
            bool flag = false;

            byte[] publicKey = certificate.GetPublicKey();
            foreach (string str1 in commonNamesFromCertSubject)
            {
                if (!SslSocket.IsWhitelistedInCertBundle(bundleInfo, str1, publicKey))
                {
                    continue;
                }
                flag = true;
                break;
            }
            if (!flag)
            {
                return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
            }
            bool flag1 = SslSocket.IsCertSignedByBlizzard(certificate);
            bool runtimeEnvironment = BattleNet.Client().GetRuntimeEnvironment() == constants.RuntimeEnvironment.Mono;
            bool flag2 = (flag1 || !runtimeEnvironment ? false : chain.ChainElements.Count == 1);

            try
            {
                if (sslPolicyErrors != SslPolicyErrors.None)
                {
                    SslPolicyErrors sslPolicyError = (flag1 || flag2 ? SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None);
                    if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None && mSslSocket.m_connection.MatchSslCertName(commonNamesFromCertSubject))
                    {
                        sslPolicyError |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    }
                    if ((sslPolicyErrors & ~sslPolicyError) != SslPolicyErrors.None)
                    {
                        SslSocket.s_log.LogWarning("Failed policy check. sslPolicyErrors: {0}, expectedPolicyErrors: {1}", new object[] { sslPolicyErrors, sslPolicyError });
                        certValidationResult = SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE;
                        return(certValidationResult);
                    }
                }
                if (chain.ChainElements != null)
                {
                    X509ChainElementEnumerator enumerator = chain.ChainElements.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        X509ChainElement current = enumerator.Current;
                        SslSocket.s_log.LogDebug("Certificate Thumbprint: {0}", new object[] { current.Certificate.Thumbprint });
                        X509ChainStatus[] chainElementStatus = current.ChainElementStatus;
                        for (int i = 0; i < (int)chainElementStatus.Length; i++)
                        {
                            X509ChainStatus x509ChainStatu = chainElementStatus[i];
                            SslSocket.s_log.LogDebug("  Certificate Status: {0}", new object[] { x509ChainStatu.Status });
                        }
                    }
                    bool flag3 = false;
                    if (flag1)
                    {
                        if (chain.ChainElements.Count == 1)
                        {
                            chain.ChainPolicy.ExtraStore.Add(SslSocket.s_rootCertificate);
                            chain.Build(new X509Certificate2(certificate));
                            flag3 = true;
                        }
                    }
                    else if (flag2 && bundleInfo.bundleCerts != null)
                    {
                        foreach (X509Certificate2 bundleCert in bundleInfo.bundleCerts)
                        {
                            chain.ChainPolicy.ExtraStore.Add(bundleCert);
                        }
                        chain.Build(new X509Certificate2(certificate));
                        flag3 = true;
                    }
                    int num = 0;
                    while (num < chain.ChainElements.Count)
                    {
                        if (chain.ChainElements[num] != null)
                        {
                            num++;
                        }
                        else
                        {
                            SslSocket.s_log.LogWarning(string.Concat("ChainElements[", num, "] is null"));
                            certValidationResult = (!flag3 ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
                            return(certValidationResult);
                        }
                    }
                    if (flag1)
                    {
                        str = (BattleNet.Client().GetMobileEnvironment() != constants.MobileEnv.PRODUCTION ? "C0805E3CF51F1A56CE9E6E35CB4F4901B68128B7" : "673D9D1072B625CAD95CB47BF0F0F512233E39FD");
                        if (chain.ChainElements[1].Certificate.Thumbprint != str)
                        {
                            SslSocket.s_log.LogWarning("Root certificate thumb print check failure");
                            SslSocket.s_log.LogWarning("  expected: {0}", new object[] { str });
                            SslSocket.s_log.LogWarning("  received: {0}", new object[] { chain.ChainElements[1].Certificate.Thumbprint });
                            certValidationResult = (!flag3 ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
                            return(certValidationResult);
                        }
                    }
                    int num1 = 0;
                    while (num1 < chain.ChainElements.Count)
                    {
                        if (DateTime.Now <= chain.ChainElements[num1].Certificate.NotAfter)
                        {
                            num1++;
                        }
                        else
                        {
                            SslSocket.s_log.LogWarning(string.Concat("ChainElements[", num1, "] certificate is expired."));
                            certValidationResult = (!flag3 ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
                            return(certValidationResult);
                        }
                    }
                    X509ChainElementEnumerator x509ChainElementEnumerator = chain.ChainElements.GetEnumerator();
                    while (x509ChainElementEnumerator.MoveNext())
                    {
                        X509ChainStatus[] x509ChainStatusArray = x509ChainElementEnumerator.Current.ChainElementStatus;
                        int num2 = 0;
                        while (num2 < (int)x509ChainStatusArray.Length)
                        {
                            X509ChainStatus x509ChainStatu1 = x509ChainStatusArray[num2];
                            if ((flag1 || flag3) && x509ChainStatu1.Status == X509ChainStatusFlags.UntrustedRoot)
                            {
                                num2++;
                            }
                            else
                            {
                                SslSocket.s_log.LogWarning("Found unexpected chain error={0}.", new object[] { x509ChainStatu1.Status });
                                certValidationResult = (!flag3 ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE);
                                return(certValidationResult);
                            }
                        }
                    }
                    X509Certificate2 x509Certificate2 = new X509Certificate2(chain.ChainElements[0].Certificate);
                    SslSocket.s_log.LogDebug("Received valid certificate from FRONT >");
                    SslSocket.s_log.LogDebug("  Subject: {0}", new object[] { x509Certificate2.Subject });
                    SslSocket.s_log.LogDebug("  Issuer: {0}", new object[] { x509Certificate2.Issuer });
                    SslSocket.s_log.LogDebug("  Version: {0}", new object[] { x509Certificate2.Version });
                    SslSocket.s_log.LogDebug("  Valid Date: {0}", new object[] { x509Certificate2.NotBefore });
                    SslSocket.s_log.LogDebug("  Expiry Date: {0}", new object[] { x509Certificate2.NotAfter });
                    SslSocket.s_log.LogDebug("  Thumbprint: {0}", new object[] { x509Certificate2.Thumbprint });
                    SslSocket.s_log.LogDebug("  Serial Number: {0}", new object[] { x509Certificate2.SerialNumber });
                    SslSocket.s_log.LogDebug("  Friendly Name: {0}", new object[] { x509Certificate2.FriendlyName });
                    SslSocket.s_log.LogDebug("  Public Key Format: {0}", new object[] { x509Certificate2.PublicKey.EncodedKeyValue.Format(true) });
                    SslSocket.s_log.LogDebug("  Raw Data Length: {0}", new object[] { (int)x509Certificate2.RawData.Length });
                    SslSocket.s_log.LogDebug("  CN: {0}", new object[] { x509Certificate2.GetNameInfo(X509NameType.DnsName, false) });
                    return(SslSocket.CertValidationResult.OK);
                }
                else
                {
                    SslSocket.s_log.LogWarning("ChainElements is null");
                    certValidationResult = SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE;
                }
            }
            catch (Exception exception)
            {
                SslSocket.s_log.LogWarning("Exception while trying to validate certificate. {0}", new object[] { exception });
                certValidationResult = SslSocket.CertValidationResult.FAILED_CERT_BUNDLE;
            }
            return(certValidationResult);
        }
예제 #11
0
        public bool IsCertificateChildOfRoot(X509Certificate2 certificate, IDictionary <string, X509Certificate2> rootCertificateDirectory)
        {
            // valid until proved otherwhise
            bool      isValid   = true;
            X509Chain x509Chain = this.CreateChain(certificate);

            // Modified chain validation of the certificate. We are not interested in Ctl lists

            X509ChainStatus status;
            int             index = 0;

            while (isValid && index < x509Chain.ChainStatus.Length)
            {
                status = x509Chain.ChainStatus[index];

                switch (status.Status)
                {
                case X509ChainStatusFlags.CtlNotSignatureValid:
                case X509ChainStatusFlags.CtlNotTimeValid:
                case X509ChainStatusFlags.CtlNotValidForUsage:
                case X509ChainStatusFlags.NoError:
                case X509ChainStatusFlags.OfflineRevocation:
                case X509ChainStatusFlags.RevocationStatusUnknown:
                {
                    // so far, still valid
                    break;
                }

                case X509ChainStatusFlags.Cyclic:
                case X509ChainStatusFlags.HasExcludedNameConstraint:
                case X509ChainStatusFlags.HasNotDefinedNameConstraint:
                case X509ChainStatusFlags.HasNotPermittedNameConstraint:
                case X509ChainStatusFlags.HasNotSupportedNameConstraint:
                case X509ChainStatusFlags.InvalidBasicConstraints:
                case X509ChainStatusFlags.InvalidExtension:
                case X509ChainStatusFlags.InvalidNameConstraints:
                case X509ChainStatusFlags.InvalidPolicyConstraints:
                case X509ChainStatusFlags.NoIssuanceChainPolicy:
                case X509ChainStatusFlags.NotSignatureValid:
                case X509ChainStatusFlags.NotTimeNested:
                case X509ChainStatusFlags.NotTimeValid:
                case X509ChainStatusFlags.NotValidForUsage:
                case X509ChainStatusFlags.PartialChain:
                case X509ChainStatusFlags.Revoked:
                case X509ChainStatusFlags.UntrustedRoot:
                {
                    this.logger.Warn("X509ChainStatusFlags '" + status.Status + "' is not valid, so the certificate '" + certificate.Subject + "' is not valid.");
                    this.logger.Debug("x509Chain.ChainStatus.Length:" + x509Chain.ChainStatus.Length + ". Index: " + index + ".");
                    isValid = false;
                    break;
                }

                default:
                {
                    this.logger.Warn("The certificate chain.ChainStatus '" + status.Status + "' is not implemented.");
                    isValid = false;
                    break;
                }
                }

                index++;
            }

            if (isValid)
            {
                // Check if the certificate has the default root certificate as its root
                string x509CertificateThumbprint = certificate.Thumbprint.ToLowerInvariant();
                if (rootCertificateDirectory.ContainsKey(x509CertificateThumbprint))
                {
                    // certificate is a root certificate - not valid
                    isValid = false;
                }
                else
                {
                    // Iterate though the chain, to validate if it contain a valid root vertificate
                    X509ChainElementCollection x509ChainElementCollection = x509Chain.ChainElements;
                    X509ChainElementEnumerator enumerator = x509ChainElementCollection.GetEnumerator();
                    X509ChainElement           x509ChainElement;
                    X509Certificate2           x509Certificate2;

                    // At this point, the certificate is not valid, until a
                    // it is proved that it has a valid root certificate
                    isValid = false;

                    while (isValid == false && enumerator.MoveNext())
                    {
                        x509ChainElement          = enumerator.Current;
                        x509Certificate2          = x509ChainElement.Certificate;
                        x509CertificateThumbprint = x509Certificate2.Thumbprint.ToLowerInvariant();
                        if (rootCertificateDirectory.ContainsKey(x509CertificateThumbprint))
                        {
                            // The current chain element is in the trusted rootCertificateDirectory
                            isValid = true;

                            // now the loop will break, as we have found a trusted root certificate
                        }
                    }

                    this.logger.Debug("Found root certificate in the root certificate list: " + isValid.ToString());
                }
            }

            return(isValid);
        }