private static SslProtocols FilterOutIncompatibleSslProtocols(SslProtocols protocols) { if (protocols.HasFlag(SslProtocols.Tls12) || protocols.HasFlag(SslProtocols.Tls13)) { #pragma warning disable 0618 // SSL2 is mutually exclusive with >= TLS1.2 // On Windows10 SSL2 flag has no effect but on earlier versions of the OS // opting into both SSL2 and >= TLS1.2 causes negotiation to always fail. protocols &= ~SslProtocols.Ssl2; #pragma warning restore 0618 } return(protocols); }
public static UnityTls.unitytls_protocol GetMaxProtocol(SslProtocols protocols) { if (protocols.HasFlag(SslProtocols.Tls12)) { return(UnityTls.unitytls_protocol.UNITYTLS_PROTOCOL_TLS_1_2); } if (protocols.HasFlag(SslProtocols.Tls11)) { return(UnityTls.unitytls_protocol.UNITYTLS_PROTOCOL_TLS_1_1); } if (protocols.HasFlag(SslProtocols.Tls)) { return(UnityTls.unitytls_protocol.UNITYTLS_PROTOCOL_TLS_1_0); } return(UnityTls.unitytls_protocol.UNITYTLS_PROTOCOL_TLS_1_2); // Default to highest range }
private static bool ProtocolsSupported(SslProtocols protocols) { var defaultParams = new ConnectionParams(); defaultParams.SslProtocols = protocols; NegotiatedParams ret = ConnectAndGetNegotiatedParams(defaultParams, defaultParams); return(ret.HasSucceeded && protocols.HasFlag(ret.Protocol)); }
/// <summary> /// Test if a given protocol is supported. /// </summary> /// <param name="ssl"></param> /// <returns></returns> public async Task <bool> IsSupportedAsync(SslProtocols ssl) { await InitialiseAsync().ConfigureAwait(false); lock (_sslProtocolsLock) { return(_sslProtocols.HasFlag(ssl)); } }
protected void InitializeClientContext(X509List certificates, SslProtocols enabledSslProtocols, SslStrength sslStrength, bool checkCertificateRevocation) { // Initialize the context with the specified ssl version // Initialize the context sslContext = new SslContext(SslMethod.SSLv23_client_method); sslContext.Options |= SslOptions.SSL_OP_NO_SSLv2; if (enabledSslProtocols.HasFlag(SslProtocols.Ssl3) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_SSLv3; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls10) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls11) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls12) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_2; } // Set the Local certificate selection callback sslContext.SetClientCertCallback(this.internalCertificateSelectionCallback); // Set the enabled cipher list sslContext.SetCipherList(GetCipherString(false, enabledSslProtocols, sslStrength)); // Set the callbacks for remote cert verification and local cert selection if (remoteCertificateSelectionCallback != null) { sslContext.SetVerify(VerifyMode.SSL_VERIFY_PEER | VerifyMode.SSL_VERIFY_FAIL_IF_NO_PEER_CERT, remoteCertificateSelectionCallback); } // Set the CA list into the store if (caCertificates != null) { X509Store store = new X509Store(caCertificates); sslContext.SetCertificateStore(store); } // Set up the read/write bio's read_bio = BIO.MemoryBuffer(false); write_bio = BIO.MemoryBuffer(false); ssl = new Ssl(sslContext); ssl.SetBIO(read_bio, write_bio); read_bio.SetClose(BIO.CloseOption.Close); write_bio.SetClose(BIO.CloseOption.Close); // Set the Ssl object into Client mode ssl.SetConnectState(); }
protected void InitializeClientContext(X509List certificates, SslProtocols enabledSslProtocols, SslStrength sslStrength, bool checkCertificateRevocation) { // Initialize the context with the specified ssl version // Initialize the context sslContext = new SslContext(SslMethod.SSLv23_client_method); sslContext.Options |= SslOptions.SSL_OP_NO_SSLv2; if (enabledSslProtocols.HasFlag(SslProtocols.Ssl3) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_SSLv3; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls10) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls11) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls12) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_2; } // Set the Local certificate selection callback sslContext.SetClientCertCallback(this.internalCertificateSelectionCallback); // Set the enabled cipher list sslContext.SetCipherList(GetCipherString(false, enabledSslProtocols, sslStrength)); // Set the callbacks for remote cert verification and local cert selection if (remoteCertificateSelectionCallback != null) { sslContext.SetVerify(VerifyMode.SSL_VERIFY_PEER | VerifyMode.SSL_VERIFY_FAIL_IF_NO_PEER_CERT, remoteCertificateSelectionCallback); } // Set the CA list into the store if (caCertificates != null) { X509Store store = new X509Store(caCertificates); sslContext.SetCertificateStore(store); } // Set up the read/write bio's read_bio = BIO.MemoryBuffer(false); write_bio = BIO.MemoryBuffer(false); ssl = new Ssl(sslContext); ssl.SetBIO(read_bio, write_bio); read_bio.SetClose(BIO.CloseOption.Close); write_bio.SetClose(BIO.CloseOption.Close); // Set the Ssl object into Client mode ssl.SetConnectState(); }
private static string ToStringExpanded(this SslProtocols p) { var list = new System.Collections.Generic.List <SslProtocols>(); foreach (var v in Enum.GetValues(typeof(SslProtocols)).Cast <SslProtocols>()) { if (v == SslProtocols.Default || v == SslProtocols.None) { continue; } if (p.HasFlag(v)) { list.Add(v); } } return(string.Join(",", list)); }
private Interop.Secur32.SecureCredential CreateSecureCredential(int version, X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { Interop.Secur32.SecureCredential.Flags flags = Interop.Secur32.SecureCredential.Flags.Zero; if (!isServer) { flags = Interop.Secur32.SecureCredential.Flags.ValidateManual | Interop.Secur32.SecureCredential.Flags.NoDefaultCred; if ((protocols.HasFlag(SslProtocols.Tls) || protocols.HasFlag(SslProtocols.Tls11) || protocols.HasFlag(SslProtocols.Tls12)) && (policy != EncryptionPolicy.AllowNoEncryption) && (policy != EncryptionPolicy.NoEncryption)) { flags |= Interop.Secur32.SecureCredential.Flags.UseStrongCrypto; } } var credential = new Interop.Secur32.SecureCredential() { rootStore = IntPtr.Zero, phMappers = IntPtr.Zero, palgSupportedAlgs = IntPtr.Zero, certContextArray = IntPtr.Zero, cCreds = 0, cMappers = 0, cSupportedAlgs = 0, dwSessionLifespan = 0, reserved = 0 }; if (policy == EncryptionPolicy.RequireEncryption) { // Prohibit null encryption cipher. credential.dwMinimumCipherStrength = 0; credential.dwMaximumCipherStrength = 0; } else if (policy == EncryptionPolicy.AllowNoEncryption) { // Allow null encryption cipher in addition to other ciphers. credential.dwMinimumCipherStrength = -1; credential.dwMaximumCipherStrength = 0; } else if (policy == EncryptionPolicy.NoEncryption) { // Suppress all encryption and require null encryption cipher only credential.dwMinimumCipherStrength = -1; credential.dwMaximumCipherStrength = -1; } else { throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), "policy"); } int _protocolFlags = 0; if (isServer) { _protocolFlags = ((int)protocols & Interop.SChannel.ServerProtocolMask); } else { _protocolFlags = ((int)protocols & Interop.SChannel.ClientProtocolMask); } credential.version = version; credential.dwFlags = flags; credential.grbitEnabledProtocols = _protocolFlags; if (certificate != null) { credential.certContextArray = certificate.Handle; credential.cCreds = 1; } return(credential); }
private Interop.Secur32.SecureCredential CreateSecureCredential(int version, X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { Interop.Secur32.SecureCredential.Flags flags = Interop.Secur32.SecureCredential.Flags.Zero; if (!isServer) { flags = Interop.Secur32.SecureCredential.Flags.ValidateManual | Interop.Secur32.SecureCredential.Flags.NoDefaultCred; if ((protocols.HasFlag(SslProtocols.Tls) || protocols.HasFlag(SslProtocols.Tls11) || protocols.HasFlag(SslProtocols.Tls12)) && (policy != EncryptionPolicy.AllowNoEncryption) && (policy != EncryptionPolicy.NoEncryption)) { flags |= Interop.Secur32.SecureCredential.Flags.UseStrongCrypto; } } var credential = new Interop.Secur32.SecureCredential() { rootStore = IntPtr.Zero, phMappers = IntPtr.Zero, palgSupportedAlgs = IntPtr.Zero, certContextArray = IntPtr.Zero, cCreds = 0, cMappers = 0, cSupportedAlgs = 0, dwSessionLifespan = 0, reserved = 0 }; if (policy == EncryptionPolicy.RequireEncryption) { // Prohibit null encryption cipher. credential.dwMinimumCipherStrength = 0; credential.dwMaximumCipherStrength = 0; } else if (policy == EncryptionPolicy.AllowNoEncryption) { // Allow null encryption cipher in addition to other ciphers. credential.dwMinimumCipherStrength = -1; credential.dwMaximumCipherStrength = 0; } else if (policy == EncryptionPolicy.NoEncryption) { // Suppress all encryption and require null encryption cipher only credential.dwMinimumCipherStrength = -1; credential.dwMaximumCipherStrength = -1; } else { throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), "policy"); } int _protocolFlags = 0; if (isServer) { _protocolFlags = ((int)protocols & Interop.SChannel.ServerProtocolMask); } else { _protocolFlags = ((int)protocols & Interop.SChannel.ClientProtocolMask); } credential.version = version; credential.dwFlags = flags; credential.grbitEnabledProtocols = _protocolFlags; if (certificate != null) { credential.certContextArray = certificate.Handle; credential.cCreds = 1; } return credential; }
/// <summary> /// Initiates the SSL connection. /// </summary> /// <param name="baseStream">The base stream.</param> /// <param name="encoding">The encoding used in the SSL connection.</param> /// <param name="connectionString">The connection string used to establish the connection.</param> /// <returns>A <see cref="MySqlStream"/> instance ready to initiate an SSL connection.</returns> public MySqlStream StartSSL(ref Stream baseStream, Encoding encoding, string connectionString) { // If SslCa connection option was provided, check for the file extension as it can also be set as a PFX file. if (_settings.SslCa != null) { var fileExtension = GetCertificateFileExtension(_settings.SslCa, true); if (fileExtension != null) { _treatCertificatesAsPemFormat = fileExtension != "pfx"; } } RemoteCertificateValidationCallback sslValidateCallback = new RemoteCertificateValidationCallback(ServerCheckValidation); SslStream ss = new SslStream(baseStream, false, sslValidateCallback, null); X509CertificateCollection certs = (_treatCertificatesAsPemFormat && _settings.CertificateStoreLocation == MySqlCertificateStoreLocation.None) ? new X509CertificateCollection() : GetPFXClientCertificates(); string connectionId = connectionString.GetHashCode().ToString(); SslProtocols tlsProtocol = SslProtocols.None; if (_settings.TlsVersion != null) { #if NET452 || NETSTANDARD2_0 if (_settings.TlsVersion.Equals("Tls13", StringComparison.OrdinalIgnoreCase)) { throw new NotSupportedException(Resources.Tlsv13NotSupported); } #endif SslProtocols sslProtocolsToUse = (SslProtocols)Enum.Parse(typeof(SslProtocols), _settings.TlsVersion); List <SslProtocols> listProtocols = new List <SslProtocols>(); #if NET48 || NETSTANDARD2_1 || NET5_0 if (sslProtocolsToUse.HasFlag((SslProtocols)12288)) { listProtocols.Add((SslProtocols)12288); } #endif if (sslProtocolsToUse.HasFlag(SslProtocols.Tls12)) { listProtocols.Add(SslProtocols.Tls12); } if (sslProtocolsToUse.HasFlag(SslProtocols.Tls11)) { listProtocols.Add(SslProtocols.Tls11); } if (sslProtocolsToUse.HasFlag(SslProtocols.Tls)) { listProtocols.Add(SslProtocols.Tls); } tlsProtocols = listProtocols.ToArray(); } lock (thisLock) { if (tlsConnectionRef.ContainsKey(connectionId)) { tlsProtocol = tlsConnectionRef[connectionId]; } else { if (!tlsRetry.ContainsKey(connectionId)) { tlsRetry[connectionId] = 0; } for (int i = tlsRetry[connectionId]; i < tlsProtocols.Length; i++) { tlsProtocol |= tlsProtocols[i]; } } try { tlsProtocol = (tlsProtocol == SslProtocols.None) ? SslProtocols.Tls : tlsProtocol; if (!ss.AuthenticateAsClientAsync(_settings.Server, certs, tlsProtocol, false).Wait((int)_settings.ConnectionTimeout * 1000)) { throw new AuthenticationException($"Authentication to host '{_settings.Server}' faied."); } tlsConnectionRef[connectionId] = tlsProtocol; tlsRetry.Remove(connectionId); } catch (AggregateException ex) { if (ex.GetBaseException() is IOException) { tlsConnectionRef.Remove(connectionId); if (tlsRetry.ContainsKey(connectionId)) { if (tlsRetry[connectionId] > tlsProtocols.Length) { throw new MySqlException(Resources.SslConnectionError, ex); } tlsRetry[connectionId] += 1; } } throw ex.GetBaseException(); } } baseStream = ss; MySqlStream stream = new MySqlStream(ss, encoding, false); stream.SequenceByte = 2; return(stream); }
private void InitializeServerContext( X509Certificate serverCertificate, bool clientCertificateRequired, X509Chain caCerts, SslProtocols enabledSslProtocols, SslStrength sslStrength, bool checkCertificateRevocation) { if (serverCertificate == null) { throw new ArgumentNullException("serverCertificate", "Server certificate cannot be null"); } if (!serverCertificate.HasPrivateKey) { throw new ArgumentException("Server certificate must have a private key", "serverCertificate"); } // Initialize the context sslContext = new SslContext(SslMethod.SSLv23_server_method); // Remove support for protocols not specified in the enabledSslProtocols sslContext.Options |= SslOptions.SSL_OP_NO_SSLv2; if (enabledSslProtocols.HasFlag(SslProtocols.Ssl3) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_SSLv3; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls10) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls11) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls12) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_2; } // Set the context mode sslContext.Mode = SslMode.SSL_MODE_AUTO_RETRY; // Set the client certificate verification callback if we are requiring client certs if (clientCertificateRequired) { sslContext.SetVerify(VerifyMode.SSL_VERIFY_PEER | VerifyMode.SSL_VERIFY_FAIL_IF_NO_PEER_CERT, remoteCertificateSelectionCallback); } else { sslContext.SetVerify(VerifyMode.SSL_VERIFY_NONE, null); } // Set the client certificate max verification depth sslContext.SetVerifyDepth(10); // Set the certificate store and ca list if (caCerts != null) { // Don't take ownership of the X509Store IntPtr. When we // SetCertificateStore, the context takes ownership of the store pointer. X509Store cert_store = new X509Store(caCerts, false); sslContext.SetCertificateStore(cert_store); Core.Stack <X509Name> name_stack = new Core.Stack <X509Name>(); foreach (X509Certificate cert in caCerts) { X509Name subject = cert.Subject; name_stack.Add(subject); } // Assign the stack to the context sslContext.CAList = name_stack; } // Set the cipher string sslContext.SetCipherList(GetCipherString(false, enabledSslProtocols, sslStrength)); // Set the certificate sslContext.UseCertificate(serverCertificate); // Set the private key sslContext.UsePrivateKey(serverCertificate.PrivateKey); // Set the session id context sslContext.SetSessionIdContext(Encoding.ASCII.GetBytes(AppDomain.CurrentDomain.FriendlyName)); }
private void InitializeServerContext( X509Certificate serverCertificate, bool clientCertificateRequired, X509Chain caCerts, SslProtocols enabledSslProtocols, SslStrength sslStrength, bool checkCertificateRevocation) { if (serverCertificate == null) { throw new ArgumentNullException("serverCertificate", "Server certificate cannot be null"); } if (!serverCertificate.HasPrivateKey) { throw new ArgumentException("Server certificate must have a private key", "serverCertificate"); } // Initialize the context sslContext = new SslContext(SslMethod.SSLv23_server_method); // Remove support for protocols not specified in the enabledSslProtocols sslContext.Options |= SslOptions.SSL_OP_NO_SSLv2; if (enabledSslProtocols.HasFlag(SslProtocols.Ssl3) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_SSLv3; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls10) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls11) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_1; } if (enabledSslProtocols.HasFlag(SslProtocols.Tls12) == false && enabledSslProtocols.HasFlag(SslProtocols.Default) == false) { sslContext.Options |= SslOptions.SSL_OP_NO_TLSv1_2; } // Set the context mode sslContext.Mode = SslMode.SSL_MODE_AUTO_RETRY; // Set the client certificate verification callback if we are requiring client certs if (clientCertificateRequired) { sslContext.SetVerify(VerifyMode.SSL_VERIFY_PEER | VerifyMode.SSL_VERIFY_FAIL_IF_NO_PEER_CERT, remoteCertificateSelectionCallback); } else { sslContext.SetVerify(VerifyMode.SSL_VERIFY_NONE, null); } // Set the client certificate max verification depth sslContext.SetVerifyDepth(10); // Set the certificate store and ca list if (caCerts != null) { // Don't take ownership of the X509Store IntPtr. When we // SetCertificateStore, the context takes ownership of the store pointer. X509Store cert_store = new X509Store(caCerts, false); sslContext.SetCertificateStore(cert_store); Core.Stack<X509Name> name_stack = new Core.Stack<X509Name>(); foreach (X509Certificate cert in caCerts) { X509Name subject = cert.Subject; name_stack.Add(subject); } // Assign the stack to the context sslContext.CAList = name_stack; } // Set the cipher string sslContext.SetCipherList(GetCipherString(false, enabledSslProtocols, sslStrength)); // Set the certificate sslContext.UseCertificate(serverCertificate); // Set the private key sslContext.UsePrivateKey(serverCertificate.PrivateKey); // Set the session id context sslContext.SetSessionIdContext(Encoding.ASCII.GetBytes(AppDomain.CurrentDomain.FriendlyName)); }