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);
        }
Beispiel #2
0
 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));
        }
Beispiel #4
0
        /// <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));
            }
        }
Beispiel #5
0
        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;
        }
Beispiel #10
0
        /// <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);
        }
Beispiel #11
0
        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));
        }