Exemple #1
0
        public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                         LocalCertificateSelectionCallback?userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
            : base(innerStream, leaveInnerStreamOpen)
        {
            if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption)
            {
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(encryptionPolicy));
            }

            _userCertificateValidationCallback = userCertificateValidationCallback;
            _userCertificateSelectionCallback  = userCertificateSelectionCallback;
            _encryptionPolicy       = encryptionPolicy;
            _certValidationDelegate = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
            _certSelectionDelegate  = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);

            _innerStream = innerStream;
        }
Exemple #2
0
        public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                         LocalCertificateSelectionCallback?userCertificateSelectionCallback, EncryptionPolicy encryptionPolicy)
            : base(innerStream, leaveInnerStreamOpen)
        {
#pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete
            if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption)
            {
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, "EncryptionPolicy"), nameof(encryptionPolicy));
            }
#pragma warning restore SYSLIB0040

            _sslAuthenticationOptions.EncryptionPolicy       = encryptionPolicy;
            _sslAuthenticationOptions.CertValidationDelegate = userCertificateValidationCallback;
            _sslAuthenticationOptions.CertSelectionDelegate  = userCertificateSelectionCallback;

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Log.SslStreamCtor(this, innerStream);
            }
        }
Exemple #3
0
        /// <summary>Creates a SessionFactory object.</summary>
        /// <param name="callback">The callback for notifications about session establishment.</param>
        /// <param name="properties">Optional properties used for communicator initialization.</param>
        /// <param name="logger">Optional logger used for communicator initialization.</param>
        /// <param name="observer">Optional communicator observer used for communicator initialization.</param>
        /// <param name="certificates">Optional certificates used by secure transports.</param>
        /// <param name="caCertificates">Optional CA certificates used by secure transports.</param>
        /// /// <param name="certificateSelectionCallback">Optional certificate selection callback used by secure
        /// transports.</param>
        /// <param name="certificateValidationCallback">Optional certificate validation callback used by secure
        /// transports.</param>
        /// <param name="passwordCallback">Optional password callback used by secure transports.</param>
        public SessionFactoryHelper(
            ISessionCallback callback,
            Dictionary <string, string> properties,
            ILogger?logger = null,
            ICommunicatorObserver?observer            = null,
            X509Certificate2Collection?certificates   = null,
            X509Certificate2Collection?caCertificates = null,
            LocalCertificateSelectionCallback?certificateSelectionCallback    = null,
            RemoteCertificateValidationCallback?certificateValidationCallback = null,
            IPasswordCallback?passwordCallback = null)
        {
            _callback       = callback;
            _properties     = properties;
            _logger         = logger;
            _observer       = observer;
            _certificates   = certificates;
            _caCertificates = caCertificates;
            _certificateSelectionCallback  = certificateSelectionCallback;
            _certificateValidationCallback = certificateValidationCallback;
            _passwordCallback = passwordCallback;

            _properties["Ice.RetryIntervals"] = "-1";
        }
Exemple #4
0
 internal SessionHelper(ISessionCallback callback,
                        string finderStr,
                        bool useCallbacks,
                        Dictionary <string, string> properties,
                        ILogger?logger,
                        ICommunicatorObserver?observer,
                        X509Certificate2Collection?certificates,
                        X509Certificate2Collection?caCertificates,
                        LocalCertificateSelectionCallback?certificateSelectionCallback,
                        RemoteCertificateValidationCallback?certificateValidationCallback,
                        IPasswordCallback?passwordCallback)
 {
     _callback       = callback;
     _finderStr      = finderStr;
     _useCallbacks   = useCallbacks;
     _properties     = properties;
     _logger         = logger;
     _observer       = observer;
     _certificates   = certificates;
     _caCertificates = caCertificates;
     _certificateSelectionCallback  = certificateSelectionCallback;
     _certificateValidationCallback = certificateValidationCallback;
     _passwordCallback = passwordCallback;
 }
Exemple #5
0
 public SslStream(Stream innerStream, bool leaveInnerStreamOpen, RemoteCertificateValidationCallback?userCertificateValidationCallback,
                  LocalCertificateSelectionCallback?userCertificateSelectionCallback)
     : this(innerStream, leaveInnerStreamOpen, userCertificateValidationCallback, userCertificateSelectionCallback, EncryptionPolicy.RequireEncryption)
 {
 }
Exemple #6
0
        internal SslEngine(
            Communicator communicator,
            X509Certificate2Collection?certificates,
            X509Certificate2Collection?caCertificates,
            LocalCertificateSelectionCallback?certificateSelectionCallback,
            RemoteCertificateValidationCallback?certificateValidationCallback,
            IPasswordCallback?passwordCallback)
        {
            _logger            = communicator.Logger;
            SecurityTraceLevel = communicator.GetPropertyAsInt("IceSSL.Trace.Security") ?? 0;
            _trustManager      = new SslTrustManager(communicator);

            CertificateSelectionCallback        = certificateSelectionCallback;
            RemoteCertificateValidationCallback = certificateValidationCallback;
            PasswordCallback = passwordCallback;

            Certs   = certificates;
            CaCerts = caCertificates;

            // Check for a default directory. We look in this directory for files mentioned in the configuration.
            _defaultDir = communicator.GetProperty("IceSSL.DefaultDir") ?? "";

            string?certStoreLocation = communicator.GetProperty("IceSSL.CertStoreLocation");

            if (certStoreLocation != null && CertificateSelectionCallback != null)
            {
                throw new InvalidConfigurationException(
                          "the property `IceSSL.CertStoreLocation' is incompatible with the certificate selection callback");
            }
            certStoreLocation ??= "CurrentUser";
            StoreLocation storeLocation;

            if (certStoreLocation == "CurrentUser")
            {
                storeLocation = StoreLocation.CurrentUser;
            }
            else if (certStoreLocation == "LocalMachine")
            {
                storeLocation = StoreLocation.LocalMachine;
            }
            else
            {
                _logger.Warning($"Invalid IceSSL.CertStoreLocation value `{certStoreLocation}' adjusted to `CurrentUser'");
                storeLocation = StoreLocation.CurrentUser;
            }
            UseMachineContext = certStoreLocation == "LocalMachine";

            // Protocols selects which protocols to enable
            SslProtocols = ParseProtocols(communicator.GetPropertyAsList("IceSSL.Protocols"));

            // VerifyDepthMax establishes the maximum length of a peer's certificate chain, including the peer's
            // certificate. A value of 0 means there is no maximum.
            int?verifyDepthMax = communicator.GetPropertyAsInt("IceSSL.VerifyDepthMax");

            if (verifyDepthMax != null && RemoteCertificateValidationCallback != null)
            {
                throw new InvalidConfigurationException(
                          "the property `IceSSL.VerifyDepthMax' check is incompatible with the custom remote certificate validation callback");
            }
            _verifyDepthMax = verifyDepthMax ?? 3;

            // CheckCRL determines whether the certificate revocation list is checked, and how strictly.
            CheckCRL = communicator.GetPropertyAsInt("IceSSL.CheckCRL") ?? 0;

            // If the user hasn't supplied a certificate collection, we need to examine the property settings.
            if (Certs == null)
            {
                // If IceSSL.CertFile is defined, load a certificate from a file and add it to the collection.
                // TODO: tracing?
                string?certFile = communicator.GetProperty("IceSSL.CertFile");
                if (certFile != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.CertFile' is incompatible with the certificate selection callback");
                }

                string?passwordStr = communicator.GetProperty("IceSSL.Password");
                if (passwordStr != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.Password' is incompatible with the certificate selection callback");
                }

                string?findCert = communicator.GetProperty("IceSSL.FindCert");
                if (findCert != null && CertificateSelectionCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.FindCert' is incompatible with the certificate selection callback");
                }
                Certs = new X509Certificate2Collection();
                const string findPrefix = "IceSSL.FindCert.";
                Dictionary <string, string> findCertProps = communicator.GetProperties(forPrefix: findPrefix);

                if (certFile != null)
                {
                    if (!CheckPath(ref certFile))
                    {
                        throw new FileNotFoundException($"certificate file not found: `{certFile}'", certFile);
                    }

                    SecureString?password = null;
                    if (passwordStr != null)
                    {
                        password = CreateSecureString(passwordStr);
                    }
                    else if (PasswordCallback != null)
                    {
                        password = PasswordCallback(certFile);
                    }

                    try
                    {
                        X509Certificate2    cert;
                        X509KeyStorageFlags importFlags;
                        if (UseMachineContext)
                        {
                            importFlags = X509KeyStorageFlags.MachineKeySet;
                        }
                        else
                        {
                            importFlags = X509KeyStorageFlags.UserKeySet;
                        }

                        if (password != null)
                        {
                            cert = new X509Certificate2(certFile, password, importFlags);
                        }
                        else
                        {
                            cert = new X509Certificate2(certFile, "", importFlags);
                        }
                        Certs.Add(cert);
                    }
                    catch (CryptographicException ex)
                    {
                        throw new InvalidConfigurationException(
                                  $"error while attempting to load certificate from `{certFile}'", ex);
                    }
                }
                else if (findCert != null)
                {
                    string certStore = communicator.GetProperty("IceSSL.CertStore") ?? "My";
                    Certs.AddRange(FindCertificates("IceSSL.FindCert", storeLocation, certStore, findCert));
                    if (Certs.Count == 0)
                    {
                        throw new InvalidConfigurationException("no certificates found");
                    }
                }
            }

            if (CaCerts == null)
            {
                string?certAuthFile = communicator.GetProperty("IceSSL.CAs");
                if (certAuthFile != null && RemoteCertificateValidationCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.CAs' is incompatible with the custom remote certificate validation callback");
                }

                bool?usePlatformCAs = communicator.GetPropertyAsBool("IceSSL.UsePlatformCAs");
                if (usePlatformCAs != null && RemoteCertificateValidationCallback != null)
                {
                    throw new InvalidConfigurationException(
                              "the property `IceSSL.UsePlatformCAs' is incompatible with the custom remote certificate validation callback");
                }

                if (RemoteCertificateValidationCallback == null)
                {
                    if (certAuthFile != null || !(usePlatformCAs ?? false))
                    {
                        CaCerts = new X509Certificate2Collection();
                    }

                    if (certAuthFile != null)
                    {
                        if (!CheckPath(ref certAuthFile))
                        {
                            throw new FileNotFoundException("CA certificate file not found: `{certAuthFile}'",
                                                            certAuthFile);
                        }

                        try
                        {
                            using FileStream fs = File.OpenRead(certAuthFile);
                            byte[] data = new byte[fs.Length];
                            fs.Read(data, 0, data.Length);

                            string strbuf = "";
                            try
                            {
                                strbuf = System.Text.Encoding.UTF8.GetString(data);
                            }
                            catch (Exception)
                            {
                                // Ignore
                            }

                            if (strbuf.Length == data.Length)
                            {
                                int  size, startpos, endpos = 0;
                                bool first = true;
                                while (true)
                                {
                                    startpos = strbuf.IndexOf("-----BEGIN CERTIFICATE-----", endpos);
                                    if (startpos != -1)
                                    {
                                        endpos = strbuf.IndexOf("-----END CERTIFICATE-----", startpos);
                                        size   = endpos - startpos + "-----END CERTIFICATE-----".Length;
                                    }
                                    else if (first)
                                    {
                                        startpos = 0;
                                        endpos   = strbuf.Length;
                                        size     = strbuf.Length;
                                    }
                                    else
                                    {
                                        break;
                                    }

                                    byte[] cert = new byte[size];
                                    Buffer.BlockCopy(data, startpos, cert, 0, size);
                                    CaCerts !.Import(cert);
                                    first = false;
                                }
                            }
                            else
                            {
                                CaCerts !.Import(data);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new InvalidConfigurationException(
                                      $"error while attempting to load CA certificate from {certAuthFile}", ex);
                        }
                    }
                }
            }
        }
Exemple #7
0
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertificateValidationCallback?remoteCallback, LocalCertificateSelectionCallback?localCallback)
        {
            // Without setting (or using) these members you will get a build exception in the unit test project.
            // The code that normally uses these in the main solution is in the implementation of SslStream.

            if (_nestedWrite == 0)
            {
            }
            _exception          = null;
            _nestedWrite        = 0;
            _handshakeCompleted = false;
        }