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