/// <summary>
        /// Verifies the server certificate by calling into ServicePointManager.ServerCertificateValidationCallback or,
        /// if the is no delegate attached to it by using the default hostname verifier.
        /// </summary>
        /// <returns><c>true</c>, if server certificate was verifyed, <c>false</c> otherwise.</returns>
        /// <param name="hostname"></param>
        /// <param name="session"></param>
        static bool verifyServerCertificate(string hostname, ISSLSession session)
        {
            var defaultVerifier = HttpsURLConnection.DefaultHostnameVerifier;

            if (ServicePointManager.ServerCertificateValidationCallback == null)
            {
                return(defaultVerifier.Verify(hostname, session));
            }

            // Convert java certificates to .NET certificates and build cert chain from root certificate
            var certificates = session.GetPeerCertificateChain();
            var chain        = new X509Chain();
            var netCerts     = certificates.Select(x => new X509Certificate2(x.GetEncoded())).ToArray();

            for (int i = 1; i < netCerts.Length; i++)
            {
                chain.ChainPolicy.ExtraStore.Add(netCerts [i]);
            }

            X509Certificate2 root = netCerts [0];

            chain.ChainPolicy.RevocationFlag      = X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode      = X509RevocationMode.NoCheck;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
            chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.AllowUnknownCertificateAuthority;

            chain.Build(root);

            //If the callback returns true, then we want it to continue with the default validation. The call back is only responsible for
            //certificate pinning. Nothing else.
            //Unless, of course, you want to use a self-signed cert in which case the above comment is incorrect.
            if (ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, System.Net.Security.SslPolicyErrors.None))
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Verifies the server certificate by calling into ServicePointManager.ServerCertificateValidationCallback or,
        /// if the is no delegate attached to it by using the default hostname verifier.
        /// </summary>
        /// <returns><c>true</c>, if server certificate was verifyed, <c>false</c> otherwise.</returns>
        /// <param name="hostname"></param>
        /// <param name="session"></param>
        bool verifyServerCertificate(string hostname, ISSLSession session)
        {
            var defaultVerifier = HttpsURLConnection.DefaultHostnameVerifier;

            if (ServicePointManager.ServerCertificateValidationCallback == null) return defaultVerifier.Verify(hostname, session);

            // Convert java certificates to .NET certificates and build cert chain from root certificate
            var certificates = session.GetPeerCertificateChain();
            var chain = new System.Security.Cryptography.X509Certificates.X509Chain();
            System.Security.Cryptography.X509Certificates.X509Certificate2 root = null;
            var errors = System.Net.Security.SslPolicyErrors.None;

            // Build certificate chain and check for errors
            if (certificates == null || certificates.Length == 0) {//no cert at all
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable;
                goto bail;
            } 

            if (certificates.Length == 1) {//no root?
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                goto bail;
            } 

            var netCerts = certificates.Select(x => new System.Security.Cryptography.X509Certificates.X509Certificate2(x.GetEncoded())).ToArray();

            for (int i = 1; i < netCerts.Length; i++) {
                chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
            }

            root = netCerts[0];

            chain.ChainPolicy.RevocationFlag = System.Security.Cryptography.X509Certificates.X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
            chain.ChainPolicy.VerificationFlags = 
                    System.Security.Cryptography.X509Certificates.X509VerificationFlags.AllowUnknownCertificateAuthority;

            if (!chain.Build(root)) {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                goto bail;
            }

            var subject = root.Subject;
            var subjectCn = cnRegex.Match(subject).Groups[1].Value;

            if (String.IsNullOrWhiteSpace(subjectCn) || !match(hostname, subjectCn)) {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch;
                goto bail;
            }

        bail:
            // Call the delegate to validate
            return ServicePointManager.ServerCertificateValidationCallback(this, root, chain, errors);
        }
예제 #3
0
        /// <summary>
        /// Verifies the server certificate by calling into ServicePointManager.ServerCertificateValidationCallback or,
        /// if the is no delegate attached to it by using the default hostname verifier.
        /// </summary>
        /// <returns><c>true</c>, if server certificate was verifyed, <c>false</c> otherwise.</returns>
        /// <param name="hostname"></param>
        /// <param name="session"></param>
        bool verifyServerCertificate(string hostname, ISSLSession session)
        {
            var defaultVerifier = HttpsURLConnection.DefaultHostnameVerifier;

            if (ServicePointManager.ServerCertificateValidationCallback == null)
            {
                return(defaultVerifier.Verify(hostname, session));
            }

            // Convert java certificates to .NET certificates and build cert chain from root certificate
            var certificates = session.GetPeerCertificateChain();
            var chain        = new System.Security.Cryptography.X509Certificates.X509Chain();

            System.Security.Cryptography.X509Certificates.X509Certificate2 root = null;
            var errors = System.Net.Security.SslPolicyErrors.None;

            // Build certificate chain and check for errors
            if (certificates == null || certificates.Length == 0)  //no cert at all
            {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateNotAvailable;
                goto bail;
            }

            if (certificates.Length == 1)  //no root?
            {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                goto bail;
            }

            var netCerts = certificates.Select(x => new System.Security.Cryptography.X509Certificates.X509Certificate2(x.GetEncoded())).ToArray();

            for (int i = 1; i < netCerts.Length; i++)
            {
                chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
            }

            root = netCerts[0];

            chain.ChainPolicy.RevocationFlag      = System.Security.Cryptography.X509Certificates.X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode      = System.Security.Cryptography.X509Certificates.X509RevocationMode.NoCheck;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
            chain.ChainPolicy.VerificationFlags   =
                System.Security.Cryptography.X509Certificates.X509VerificationFlags.AllowUnknownCertificateAuthority;

            if (!chain.Build(root))
            {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors;
                goto bail;
            }

            var subject   = root.Subject;
            var subjectCn = cnRegex.Match(subject).Groups[1].Value;

            if (String.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(hostname, subjectCn))
            {
                errors = System.Net.Security.SslPolicyErrors.RemoteCertificateNameMismatch;
                goto bail;
            }

bail:
            // Call the delegate to validate
            return(ServicePointManager.ServerCertificateValidationCallback(this, root, chain, errors));
        }
        /// <summary>
        /// Verifies the server certificate by calling into ServicePointManager.ServerCertificateValidationCallback or,
        /// if the is no delegate attached to it by using the default hostname verifier.
        /// </summary>
        /// <returns><c>true</c>, if server certificate was verifyed, <c>false</c> otherwise.</returns>
        /// <param name="hostname"></param>
        /// <param name="session"></param>
        public bool Verify(string hostname, ISSLSession session)
        {
            var errors = SslPolicyErrors.None;

            if (nativeHandler.TLSConfig.DangerousAcceptAnyServerCertificateValidator)
            {
                goto sslErrorVerify;
            }

            // Convert java certificates to .NET certificates and build cert chain from root certificate
            var serverCertChain = session.GetPeerCertificateChain();

            var netCerts = serverCertChain.Select(x => new X509Certificate2(x.GetEncoded())).ToList();

            switch (nativeHandler.PinningMode)
            {
            case "CertificateOnly":

                var chain             = new X509Chain();
                X509Certificate2 root = null;

                // Build certificate chain and check for errors
                if (serverCertChain == null || serverCertChain.Length == 0)
                {    //no cert at all
                    errors = SslPolicyErrors.RemoteCertificateNotAvailable;
                    PinningFailureMessage = FailureMessages.NoCertAtAll;
                    goto sslErrorVerify;
                }

                if (serverCertChain.Length == 1)
                {    //no root?
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    PinningFailureMessage = FailureMessages.NoRoot;
                    goto sslErrorVerify;
                }

                for (int i = 1; i < netCerts.Count; i++)
                {
                    chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
                }

                chain.ChainPolicy.RevocationFlag      = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode      = X509RevocationMode.NoCheck;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                chain.ChainPolicy.VerificationFlags   = X509VerificationFlags.AllowUnknownCertificateAuthority;

                root = netCerts[0];

                if (!chain.Build(root))
                {
                    errors = SslPolicyErrors.RemoteCertificateChainErrors;
                    PinningFailureMessage = FailureMessages.ChainError;
                    goto sslErrorVerify;
                }

                var subject   = root.Subject;
                var subjectCn = cnRegex.Match(subject).Groups[1].Value;

                if (string.IsNullOrWhiteSpace(subjectCn) || !Utility.MatchHostnameToPattern(hostname, subjectCn))
                {
                    var subjectAn = root.ParseSubjectAlternativeName();

                    if (subjectAn.FirstOrDefault(s => Utility.MatchHostnameToPattern(hostname, s)) == null)
                    {
                        errors = SslPolicyErrors.RemoteCertificateNameMismatch;
                        PinningFailureMessage = FailureMessages.SubjectNameMismatch;
                        goto sslErrorVerify;
                    }
                }
                break;

            case "PublicKeysOnly":

                if (nativeHandler.CertificatePinner != null)
                {
                    if (!nativeHandler.CertificatePinner.HasPins(hostname))
                    {
                        errors = SslPolicyErrors.RemoteCertificateNameMismatch;
                        PinningFailureMessage = FailureMessages.NoPinsProvided + " " + hostname;
                    }

                    // CertificatePinner.Check will be done by Square.OkHttp3.CertificatePinner
                }
                break;
            }

sslErrorVerify:
            return(errors == SslPolicyErrors.None);
        }
        /// <summary>
        /// Verifies the server certificate by calling into ServicePointManager.ServerCertificateValidationCallback or,
        /// if the is no delegate attached to it by using the default hostname verifier.
        /// </summary>
        /// <returns><c>true</c>, if server certificate was verifyed, <c>false</c> otherwise.</returns>
        /// <param name="hostname"></param>
        /// <param name="session"></param>
        static bool verifyServerCertificate(string hostname, ISSLSession session)
        {
            var defaultVerifier = HttpsURLConnection.DefaultHostnameVerifier;

            if (ServicePointManager.ServerCertificateValidationCallback == null) return defaultVerifier.Verify(hostname, session);

            // Convert java certificates to .NET certificates and build cert chain from root certificate
            var certificates = session.GetPeerCertificateChain();
            var chain = new X509Chain();
            var netCerts = certificates.Select(x => new X509Certificate2(x.GetEncoded())).ToArray();

            for (int i = 1; i < netCerts.Length; i++) {
                chain.ChainPolicy.ExtraStore.Add(netCerts[i]);
            }

            X509Certificate2 root = netCerts[0];

            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
            chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;

            chain.Build(root);
          
            //If the callback returns true, then we want it to continue with the default validation. The call back is only responsible for 
            //certificate pinning. Nothing else. 
            if (ServicePointManager.ServerCertificateValidationCallback(hostname, root, chain, System.Net.Security.SslPolicyErrors.None)) 
            {
                return defaultVerifier.Verify(hostname, session);
            }

            return false;
        }