private static SslSocket.CertValidationResult IsServerCertificateValid(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { SslStream key = (SslStream)sender; SslSocket.SslStreamValidateContext sslStreamValidateContext = SslSocket.s_streamValidationContexts[key]; SslSocket sslSocket = sslStreamValidateContext.m_sslSocket; SslCertBundleSettings bundleSettings = sslSocket.m_bundleSettings; if (bundleSettings.bundle == null || !bundleSettings.bundle.IsUsingCertBundle) { return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } List <string> commonNamesFromCertSubject = SslSocket.GetCommonNamesFromCertSubject(certificate.Subject); SslSocket.BundleInfo bundleInfo = default(SslSocket.BundleInfo); byte[] unsignedBundleBytes = bundleSettings.bundle.CertBundleBytes; if (bundleSettings.bundle.isCertBundleSigned) { if (!SslSocket.VerifyBundleSignature(bundleSettings.bundle.CertBundleBytes)) { return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } unsignedBundleBytes = SslSocket.GetUnsignedBundleBytes(bundleSettings.bundle.CertBundleBytes); } if (!SslSocket.GetBundleInfo(unsignedBundleBytes, out bundleInfo)) { return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } bool flag = false; byte[] publicKey = certificate.GetPublicKey(); foreach (string uri in commonNamesFromCertSubject) { if (SslSocket.IsWhitelistedInCertBundle(bundleInfo, uri, publicKey)) { flag = true; break; } } if (!flag) { return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } bool flag2 = SslSocket.IsCertSignedByBlizzard(certificate); bool flag3 = BattleNet.Client().GetRuntimeEnvironment() == constants.RuntimeEnvironment.Mono; bool flag4 = !flag2 && flag3 && chain.ChainElements.Count == 1; try { if (sslPolicyErrors != SslPolicyErrors.None) { SslPolicyErrors sslPolicyErrors2 = (!flag2 && !flag4) ? SslPolicyErrors.None : (SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNotAvailable); if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None && sslSocket.m_connection.MatchSslCertName(commonNamesFromCertSubject)) { sslPolicyErrors2 |= SslPolicyErrors.RemoteCertificateNameMismatch; } if ((sslPolicyErrors & ~(sslPolicyErrors2 != SslPolicyErrors.None)) != SslPolicyErrors.None) { SslSocket.s_log.LogWarning("Failed policy check. sslPolicyErrors: {0}, expectedPolicyErrors: {1}", new object[] { sslPolicyErrors, sslPolicyErrors2 }); return(SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE); } } if (chain.ChainElements == null) { SslSocket.s_log.LogWarning("ChainElements is null"); return(SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE); } foreach (X509ChainElement x509ChainElement in chain.ChainElements) { SslSocket.s_log.LogDebug("Certificate Thumbprint: {0}", new object[] { x509ChainElement.Certificate.Thumbprint }); foreach (X509ChainStatus x509ChainStatus in x509ChainElement.ChainElementStatus) { SslSocket.s_log.LogDebug(" Certificate Status: {0}", new object[] { x509ChainStatus.Status }); } } bool flag5 = false; if (flag2) { if (chain.ChainElements.Count == 1) { chain.ChainPolicy.ExtraStore.Add(SslSocket.s_rootCertificate); chain.Build(new X509Certificate2(certificate)); flag5 = true; } } else if (flag4 && bundleInfo.bundleCerts != null) { foreach (X509Certificate2 certificate2 in bundleInfo.bundleCerts) { chain.ChainPolicy.ExtraStore.Add(certificate2); } chain.Build(new X509Certificate2(certificate)); flag5 = true; } for (int j = 0; j < chain.ChainElements.Count; j++) { if (chain.ChainElements[j] == null) { SslSocket.s_log.LogWarning("ChainElements[" + j + "] is null"); return((!flag5) ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } } if (flag2) { string text; if (BattleNet.Client().GetMobileEnvironment() == constants.MobileEnv.PRODUCTION) { text = "673D9D1072B625CAD95CB47BF0F0F512233E39FD"; } else { text = "C0805E3CF51F1A56CE9E6E35CB4F4901B68128B7"; } if (chain.ChainElements[1].Certificate.Thumbprint != text) { SslSocket.s_log.LogWarning("Root certificate thumb print check failure"); SslSocket.s_log.LogWarning(" expected: {0}", new object[] { text }); SslSocket.s_log.LogWarning(" received: {0}", new object[] { chain.ChainElements[1].Certificate.Thumbprint }); return((!flag5) ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } } for (int k = 0; k < chain.ChainElements.Count; k++) { if (DateTime.Now > chain.ChainElements[k].Certificate.NotAfter) { SslSocket.s_log.LogWarning("ChainElements[" + k + "] certificate is expired."); return((!flag5) ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } } foreach (X509ChainElement x509ChainElement2 in chain.ChainElements) { foreach (X509ChainStatus x509ChainStatus2 in x509ChainElement2.ChainElementStatus) { if ((!flag2 && !flag5) || x509ChainStatus2.Status != X509ChainStatusFlags.UntrustedRoot) { SslSocket.s_log.LogWarning("Found unexpected chain error={0}.", new object[] { x509ChainStatus2.Status }); return((!flag5) ? SslSocket.CertValidationResult.FAILED_SERVER_RESPONSE : SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } } } X509Certificate2 x509Certificate = new X509Certificate2(chain.ChainElements[0].Certificate); SslSocket.s_log.LogDebug("Received valid certificate from FRONT >"); SslSocket.s_log.LogDebug(" Subject: {0}", new object[] { x509Certificate.Subject }); SslSocket.s_log.LogDebug(" Issuer: {0}", new object[] { x509Certificate.Issuer }); SslSocket.s_log.LogDebug(" Version: {0}", new object[] { x509Certificate.Version }); SslSocket.s_log.LogDebug(" Valid Date: {0}", new object[] { x509Certificate.NotBefore }); SslSocket.s_log.LogDebug(" Expiry Date: {0}", new object[] { x509Certificate.NotAfter }); SslSocket.s_log.LogDebug(" Thumbprint: {0}", new object[] { x509Certificate.Thumbprint }); SslSocket.s_log.LogDebug(" Serial Number: {0}", new object[] { x509Certificate.SerialNumber }); SslSocket.s_log.LogDebug(" Friendly Name: {0}", new object[] { x509Certificate.FriendlyName }); SslSocket.s_log.LogDebug(" Public Key Format: {0}", new object[] { x509Certificate.PublicKey.EncodedKeyValue.Format(true) }); SslSocket.s_log.LogDebug(" Raw Data Length: {0}", new object[] { x509Certificate.RawData.Length }); SslSocket.s_log.LogDebug(" CN: {0}", new object[] { x509Certificate.GetNameInfo(X509NameType.DnsName, false) }); } catch (Exception ex) { SslSocket.s_log.LogWarning("Exception while trying to validate certificate. {0}", new object[] { ex }); return(SslSocket.CertValidationResult.FAILED_CERT_BUNDLE); } return(SslSocket.CertValidationResult.OK); }
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); }