private void ConnectCallback() { try { this.ResolveSSLAddress(); byte[] certBundleBytes; if (FileUtil.LoadFromDrive(SslSocket.GetBundleStoragePath(), out certBundleBytes)) { this.m_bundleSettings.bundle = new SslCertBundle(certBundleBytes); } RemoteCertificateValidationCallback userCertificateValidationCallback = new RemoteCertificateValidationCallback(SslSocket.OnValidateServerCertificate); this.m_sslStream = new SslStream(new NetworkStream(this.Socket, true), false, userCertificateValidationCallback); SslSocket.SslStreamValidateContext sslStreamValidateContext = new SslSocket.SslStreamValidateContext(); sslStreamValidateContext.m_sslSocket = this; SslSocket.s_streamValidationContexts.Add(this.m_sslStream, sslStreamValidateContext); this.m_sslStream.BeginAuthenticateAsClient(this.m_address, new AsyncCallback(this.OnAuthenticateAsClient), null); } catch (Exception ex) { SslSocket.s_log.LogError("Exception while trying to authenticate. {0}", new object[] { ex }); this.ExecuteBeginConnectDelegate(true); } }
private static bool OnValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { SslSocket.CertValidationResult certValidationResult = SslSocket.IsServerCertificateValid(sender, certificate, chain, sslPolicyErrors); if (certValidationResult == SslSocket.CertValidationResult.FAILED_CERT_BUNDLE) { SslStream key = (SslStream)sender; SslSocket.SslStreamValidateContext sslStreamValidateContext = SslSocket.s_streamValidationContexts[key]; SslSocket sslSocket = sslStreamValidateContext.m_sslSocket; UrlDownloaderConfig bundleDownloadConfig = sslSocket.m_bundleSettings.bundleDownloadConfig; List <SslCertBundle> list = SslSocket.DownloadCertBundles(bundleDownloadConfig); foreach (SslCertBundle sslCertBundle in list) { sslSocket.m_bundleSettings.bundle = sslCertBundle; certValidationResult = SslSocket.IsServerCertificateValid(sender, certificate, chain, sslPolicyErrors); if (certValidationResult == SslSocket.CertValidationResult.OK) { FileUtil.StoreToDrive(sslCertBundle.CertBundleBytes, SslSocket.GetBundleStoragePath(), true, true); break; } } } return(certValidationResult == SslSocket.CertValidationResult.OK); }
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); }