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); }
/// <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); } }
/// <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); } }
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; } } }
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()); } }
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); } }
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); }
/// <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); }
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); }