예제 #1
0
        private static X509Certificate2[] LoadTrustedFile(string trustedFile)
        {
            // The TrustedFile is a file containing the public keys, in PEM format of the trusted
            // root certificates that this client is willing to accept TLS connections from.
            if (!string.IsNullOrWhiteSpace(trustedFile) && File.Exists(trustedFile))
            {
                try
                {
                    var trustedRootCertificatesPem = File.ReadAllText(trustedFile, Encoding.ASCII);

                    var parser           = new PemParser();
                    var rootCertificates =
                        parser.ParseCertificates(trustedRootCertificatesPem).ToArray();

                    return(rootCertificates);
                }
                catch (CryptographicException e)
                {
                    throw new AseException("Failed to extract a public key from the TrustedFile.", e);
                }
                catch (Exception e) when(e is PathTooLongException || e is FileNotFoundException || e is DirectoryNotFoundException || e is UnauthorizedAccessException)
                {
                    throw new AseException("Failed to open the TrustedFile.", e);
                }
            }

            return(null);
        }
예제 #2
0
        private bool UserCertificateValidationCallback(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            var certificateChainPolicyErrors = (sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors;
            var otherPolicyErrors            = (sslPolicyErrors & ~SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None;

            // We're not concerned with chain errors as we verify the chain below.
            if (otherPolicyErrors)
            {
                Logger.Instance?.WriteLine($"{nameof(InternalConnectionFactory)}.{nameof(UserCertificateValidationCallback)} secure connection failed due to policy errors: {sslPolicyErrors}");
                return(false);
            }

            var untrustedRootChainStatusFlags = false;
            var otherChainStatusFlags         = false;

            // We're not concerned with UntrustedRoot errors as we verify that below.
            foreach (var status in chain.ChainStatus)
            {
                untrustedRootChainStatusFlags |= (status.Status & X509ChainStatusFlags.UntrustedRoot) == X509ChainStatusFlags.UntrustedRoot;
                otherChainStatusFlags         |= (status.Status & ~X509ChainStatusFlags.UntrustedRoot) != X509ChainStatusFlags.NoError;

                if (otherChainStatusFlags)
                {
                    Logger.Instance?.WriteLine($"{nameof(InternalConnectionFactory)}.{nameof(UserCertificateValidationCallback)} secure connection failed due to chain status: {status.Status}");
                    return(false);
                }
            }

            if (!(certificateChainPolicyErrors || untrustedRootChainStatusFlags))
            {
                //No chain Errors, we will trust the server certificate.
                return(true);
            }

            // The TrustedFile is a file containing the public keys, in PEM format of the trusted
            // root certificates that this client is willing to accept TLS connections from.
            if (!string.IsNullOrWhiteSpace(_parameters.TrustedFile) && File.Exists(_parameters.TrustedFile))
            {
                try
                {
                    var trustedRootCertificatesPem = File.ReadAllText(_parameters.TrustedFile, Encoding.ASCII);

                    var parser           = new PemParser();
                    var rootCertificates =
                        parser.ParseCertificates(trustedRootCertificatesPem)
                        .ToDictionary(GetCertificateKey);

                    // If the server certificate itself is the root, weird, but ok.
                    if (rootCertificates.ContainsKey(GetCertificateKey(serverCertificate)))
                    {
                        return(true);
                    }

                    // If any certificates in the chain are trusted, then we will trust the server certificate.
                    foreach (var chainElement in chain.ChainElements)
                    {
                        var key = GetCertificateKey(chainElement.Certificate);

                        if (rootCertificates.ContainsKey(key))
                        {
                            return(true);
                        }
                    }
                }
                catch (CryptographicException e)
                {
                    throw new AseException("Failed to extract a public key from the TrustedFile.", e);
                }
                catch (Exception e) when(e is PathTooLongException || e is FileNotFoundException || e is DirectoryNotFoundException || e is UnauthorizedAccessException)
                {
                    throw new AseException("Failed to open the TrustedFile.", e);
                }
            }

            Logger.Instance?.WriteLine($"{nameof(InternalConnectionFactory)}.{nameof(UserCertificateValidationCallback)} secure connection failed due to missing root or intermediate certificate in the certificate store, or the TrustedFile.");

            return(false);
        }