Example #1
0
		internal static RemoteCertificateValidationCallback InternalToPublic (string hostname, RemoteCertValidationCallback callback)
		{
			if (callback == null)
				return null;

			return (s, c, ch, e) => callback (hostname, c, ch, e);
		}
Example #2
0
		internal static MSI.MonoRemoteCertificateValidationCallback InternalToMono (RemoteCertValidationCallback callback)
		{
			if (callback == null)
				return null;

			return (h, c, ch, e) => callback (h, c, (X509Chain)(object)ch, (SslPolicyErrors)e);
		}
Example #3
0
 //
 //  The public Client and Server classes enforce the parameters rules before
 //  calling into this .ctor.
 //
 internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy)
 {
     _innerStream = innerStream;
     _reader = new FixedSizeReader(innerStream);
     _certValidationDelegate = certValidationCallback;
     _certSelectionDelegate = certSelectionCallback;
     _encryptionPolicy = encryptionPolicy;
 }
Example #4
0
		internal static SSPIInterface Create (string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates,
		                                           bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy,
		                                           LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig)
		{
			if (userConfig.Settings != null && remoteValidationCallback != null)
				throw new InvalidOperationException ();
			var context = userConfig.Provider.CreateTlsContext (
				hostname, serverMode, (TlsProtocols)protocolFlags, serverCertificate, clientCertificates,
				remoteCertRequired, checkCertName, checkCertRevocationStatus,
				(MonoEncryptionPolicy)encryptionPolicy, userConfig.Settings);
			return new SSPIInterface (context, userConfig.EventSink);
		}
 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.GetString("net_invalid_enum", new object[] { "EncryptionPolicy" }), "encryptionPolicy");
     }
     this._userCertificateValidationCallback = userCertificateValidationCallback;
     this._userCertificateSelectionCallback = userCertificateSelectionCallback;
     RemoteCertValidationCallback certValidationCallback = new RemoteCertValidationCallback(this.userCertValidationCallbackWrapper);
     LocalCertSelectionCallback certSelectionCallback = (userCertificateSelectionCallback == null) ? null : new LocalCertSelectionCallback(this.userCertSelectionCallbackWrapper);
     this._SslState = new SslState(innerStream, certValidationCallback, certSelectionCallback, encryptionPolicy);
 }
Example #6
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;
            RemoteCertValidationCallback _userCertValidationCallbackWrapper = new RemoteCertValidationCallback(UserCertValidationCallbackWrapper);
            LocalCertSelectionCallback _userCertSelectionCallbackWrapper = userCertificateSelectionCallback == null ? null : new LocalCertSelectionCallback(UserCertSelectionCallbackWrapper);
            _sslState = new SslState(innerStream, _userCertValidationCallbackWrapper, _userCertSelectionCallbackWrapper, encryptionPolicy);
        }
Example #7
0
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?localCallback)
        {
            ThrowIfExceptional();

            if (_context != null && _context.IsValidContext)
            {
                throw new InvalidOperationException(SR.net_auth_reauth);
            }

            if (_context != null && IsServer)
            {
                throw new InvalidOperationException(SR.net_auth_client_server);
            }

            if (sslClientAuthenticationOptions.TargetHost == null)
            {
                throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost));
            }

            _exception = null;
            try
            {
                _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback);
                _context = new SecureChannel(_sslAuthenticationOptions, this);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
 internal unsafe bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
 {
     SslPolicyErrors none = SslPolicyErrors.None;
     bool flag = false;
     X509Chain chain = null;
     X509Certificate2 remoteCertificate = null;
     try
     {
         X509Certificate2Collection certificates;
         remoteCertificate = this.GetRemoteCertificate(out certificates);
         this.m_IsRemoteCertificateAvailable = remoteCertificate != null;
         if (remoteCertificate == null)
         {
             none |= SslPolicyErrors.RemoteCertificateNotAvailable;
         }
         else
         {
             chain = new X509Chain {
                 ChainPolicy = { RevocationMode = this.m_CheckCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, RevocationFlag = X509RevocationFlag.ExcludeRoot }
             };
             if (certificates != null)
             {
                 chain.ChainPolicy.ExtraStore.AddRange(certificates);
             }
             if (!chain.Build(remoteCertificate) && (chain.ChainContext == IntPtr.Zero))
             {
                 throw new CryptographicException(Marshal.GetLastWin32Error());
             }
             if (this.m_CheckCertName)
             {
                 ChainPolicyParameter cpp = new ChainPolicyParameter {
                     cbSize = ChainPolicyParameter.StructSize,
                     dwFlags = 0
                 };
                 SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_extra_cert_chain_policy_para = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(this.IsServer);
                 cpp.pvExtraPolicyPara = &ssl_extra_cert_chain_policy_para;
                 fixed (char* str = ((char*) this.m_HostName))
                 {
                     char* chPtr = str;
                     ssl_extra_cert_chain_policy_para.pwszServerName = chPtr;
                     cpp.dwFlags |= 0xfbf;
                     SafeFreeCertChain chainContext = new SafeFreeCertChain(chain.ChainContext);
                     if (PolicyWrapper.VerifyChainPolicy(chainContext, ref cpp) == 0x800b010f)
                     {
                         none |= SslPolicyErrors.RemoteCertificateNameMismatch;
                     }
                 }
             }
             X509ChainStatus[] chainStatus = chain.ChainStatus;
             if ((chainStatus != null) && (chainStatus.Length != 0))
             {
                 none |= SslPolicyErrors.RemoteCertificateChainErrors;
             }
         }
         if (remoteCertValidationCallback != null)
         {
             flag = remoteCertValidationCallback(this.m_HostName, remoteCertificate, chain, none);
         }
         else if ((none == SslPolicyErrors.RemoteCertificateNotAvailable) && !this.m_RemoteCertRequired)
         {
             flag = true;
         }
         else
         {
             flag = none == SslPolicyErrors.None;
         }
         if (!Logging.On)
         {
             return flag;
         }
         if (none != SslPolicyErrors.None)
         {
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_errors"));
             if ((none & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None)
             {
                 Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_not_available"));
             }
             if ((none & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None)
             {
                 Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_name_mismatch"));
             }
             if ((none & SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None)
             {
                 foreach (X509ChainStatus status in chain.ChainStatus)
                 {
                     Logging.PrintInfo(Logging.Web, this, "\t" + status.StatusInformation);
                 }
             }
         }
         if (flag)
         {
             if (remoteCertValidationCallback != null)
             {
                 Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_valid"));
                 return flag;
             }
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_no_errors"));
             return flag;
         }
         if (remoteCertValidationCallback != null)
         {
             Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_invalid"));
         }
     }
     finally
     {
         if (chain != null)
         {
             chain.Reset();
         }
         if (remoteCertificate != null)
         {
             remoteCertificate.Reset();
         }
     }
     return flag;
 }
Example #9
0
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate");
            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;
            // we don't catch exceptions in this method, so it's safe for "accepted" be initialized with true
            bool success = false;

            X509Chain chain = null;
            X509Certificate2 remoteCertificateEx = null;

            try {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx = GetRemoteCertificate(out remoteCertificateStore);
                m_IsRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!m_RemoteCertRequired).ToString());
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
#if !MONO
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = m_CheckCertRevocation? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);

                    if (!chain.Build(remoteCertificateEx)       // Build failed on handle or on policy
                        && chain.ChainContext == IntPtr.Zero)   // Build failed to generate a valid handle
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (m_CheckCertName)
                    {
                        unsafe {
                            uint status = 0;
                            ChainPolicyParameter cppStruct = new ChainPolicyParameter();
                            cppStruct.cbSize  = ChainPolicyParameter.StructSize;
                            cppStruct.dwFlags = 0;


                            SSL_EXTRA_CERT_CHAIN_POLICY_PARA eppStruct = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(IsServer);
                            cppStruct.pvExtraPolicyPara = &eppStruct;

                            fixed (char* namePtr = m_HostName) {
                                eppStruct.pwszServerName = namePtr;
                                cppStruct.dwFlags |= (int) (IgnoreCertProblem.none & ~IgnoreCertProblem.invalid_name);

                                SafeFreeCertChain chainContext= new SafeFreeCertChain(chain.ChainContext);
                                status = PolicyWrapper.VerifyChainPolicy(chainContext, ref cppStruct);
                                if ((CertificateProblem) status ==  CertificateProblem.CertCN_NO_MATCH)
                                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                            }
                        }
                    }

                    X509ChainStatus[] chainStatusArray = chain.ChainStatus;
                    if (chainStatusArray != null && chainStatusArray.Length != 0)
                        sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;

                }

                if (remoteCertValidationCallback != null) {
                    success = remoteCertValidationCallback(m_HostName, remoteCertificateEx, chain, sslPolicyErrors);
                } else {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !m_RemoteCertRequired)
                        success = true;
                    else
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                }
#else
		success = SSPIWrapper.CheckRemoteCertificate(m_SecurityContext);
#endif

                if (Logging.On) {
                    if (sslPolicyErrors != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_errors));
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_not_available));
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString(SR.net_log_remote_cert_name_mismatch));
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                            foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                                Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation);
                    }
                    if (success)
                    {
                        if (remoteCertValidationCallback != null)
                            Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_valid));
                        else
                            Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_has_no_errors));
                    }
                    else
                    {
                        if (remoteCertValidationCallback != null)
                            Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_remote_cert_user_declared_invalid));
                    }
                }
                GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null? "<null>": remoteCertificateEx.ToString(true)));
            }
            finally {
                // At least on Win2k server the chain is found to have dependancies on the original cert context.
                // So it should be closed first.
                if (chain != null) {
                    chain.Reset();
                }
                if (remoteCertificateEx != null)
                    remoteCertificateEx.Reset();
            }
            GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            return success;
        }
Example #10
0
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?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)
            {
            }
            _context             = null;
            _exception           = null;
            _internalBuffer      = null;
            _internalBufferCount = 0;
            _internalOffset      = 0;
            _nestedWrite         = 0;
            _handshakeCompleted  = false;
        }
Example #11
0
        /*++
            VerifyRemoteCertificate - Validates the content of a Remote Certificate

            checkCRL if true, checks the certificate revocation list for validity.
            checkCertName, if true checks the CN field of the certificate
        --*/

        //This method validates a remote certificate.
        //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build
        //          A user callback has unique signature so it is safe to call it under permission assert.
        //
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate");
            }

            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;

            // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true.
            bool success = false;
            X509Chain chain = null;
            X509Certificate2 remoteCertificateEx = null;

            try
            {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore);
                _isRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString());
                    }
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
                    }

                    sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties(
                        chain,
                        remoteCertificateEx,
                        _checkCertName,
                        _serverMode,
                        _hostName);
                }

                if (remoteCertValidationCallback != null)
                {
                    success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors);
                }
                else
                {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired)
                    {
                        success = true;
                    }
                    else
                    {
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                    }
                }

                if (SecurityEventSource.Log.IsEnabled())
                {
                    if (sslPolicyErrors != SslPolicyErrors.None)
                    {
                        SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors);
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                        {
                            SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                        {
                            SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                        {
                            string chainStatusString = "ChainStatus: ";
                            foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                            {
                                chainStatusString += "\t" + chainStatus.StatusInformation;
                            }
                            SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString);
                        }
                    }
                    if (success)
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this));
                        }
                        else
                        {
                            SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this));
                        }
                    }
                    else
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this));
                        }
                    }
                }

                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true)));
                }
            }
            finally
            {
                // At least on Win2k server the chain is found to have dependencies on the original cert context.
                // So it should be closed first.
                if (chain != null)
                {
                    chain.Dispose();
                }

                if (remoteCertificateEx != null)
                {
                    remoteCertificateEx.Dispose();
                }
            }

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            }
            return success;
        }
Example #12
0
        internal unsafe bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            SslPolicyErrors  none              = SslPolicyErrors.None;
            bool             flag              = false;
            X509Chain        chain             = null;
            X509Certificate2 remoteCertificate = null;

            try
            {
                X509Certificate2Collection certificates;
                remoteCertificate = this.GetRemoteCertificate(out certificates);
                this.m_IsRemoteCertificateAvailable = remoteCertificate != null;
                if (remoteCertificate == null)
                {
                    none |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain {
                        ChainPolicy = { RevocationMode = this.m_CheckCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, RevocationFlag = X509RevocationFlag.ExcludeRoot }
                    };
                    if (certificates != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(certificates);
                    }
                    if (!chain.Build(remoteCertificate) && (chain.ChainContext == IntPtr.Zero))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (this.m_CheckCertName)
                    {
                        ChainPolicyParameter cpp = new ChainPolicyParameter {
                            cbSize  = ChainPolicyParameter.StructSize,
                            dwFlags = 0
                        };
                        SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_extra_cert_chain_policy_para = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(this.IsServer);
                        cpp.pvExtraPolicyPara = &ssl_extra_cert_chain_policy_para;
                        fixed(char *str = ((char *)this.m_HostName))
                        {
                            char *chPtr = str;

                            ssl_extra_cert_chain_policy_para.pwszServerName = chPtr;
                            cpp.dwFlags |= 0xfbf;
                            SafeFreeCertChain chainContext = new SafeFreeCertChain(chain.ChainContext);

                            if (PolicyWrapper.VerifyChainPolicy(chainContext, ref cpp) == 0x800b010f)
                            {
                                none |= SslPolicyErrors.RemoteCertificateNameMismatch;
                            }
                        }
                    }
                    X509ChainStatus[] chainStatus = chain.ChainStatus;
                    if ((chainStatus != null) && (chainStatus.Length != 0))
                    {
                        none |= SslPolicyErrors.RemoteCertificateChainErrors;
                    }
                }
                if (remoteCertValidationCallback != null)
                {
                    flag = remoteCertValidationCallback(this.m_HostName, remoteCertificate, chain, none);
                }
                else if ((none == SslPolicyErrors.RemoteCertificateNotAvailable) && !this.m_RemoteCertRequired)
                {
                    flag = true;
                }
                else
                {
                    flag = none == SslPolicyErrors.None;
                }
                if (!Logging.On)
                {
                    return(flag);
                }
                if (none != SslPolicyErrors.None)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_errors"));
                    if ((none & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_not_available"));
                    }
                    if ((none & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_name_mismatch"));
                    }
                    if ((none & SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None)
                    {
                        foreach (X509ChainStatus status in chain.ChainStatus)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + status.StatusInformation);
                        }
                    }
                }
                if (flag)
                {
                    if (remoteCertValidationCallback != null)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_valid"));
                        return(flag);
                    }
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_no_errors"));
                    return(flag);
                }
                if (remoteCertValidationCallback != null)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_invalid"));
                }
            }
            finally
            {
                if (chain != null)
                {
                    chain.Reset();
                }
                if (remoteCertificate != null)
                {
                    remoteCertificate.Reset();
                }
            }
            return(flag);
        }
Example #13
0
 internal void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
 {
 }
Example #14
0
        /*++
         *  VerifyRemoteCertificate - Validates the content of a Remote Certificate
         *
         *  checkCRL if true, checks the certificate revocation list for validity.
         *  checkCertName, if true checks the CN field of the certificate
         * --*/

        //This method validates a remote certificate.
        //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build
        //          A user callback has unique signature so it is safe to call it under permission assert.
        //
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate");
            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;

            // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true.
            bool             success             = false;
            X509Chain        chain               = null;
            X509Certificate2 remoteCertificateEx = null;

            try
            {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx           = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore);
                _isRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString());
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
                    }

                    sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties(
                        chain,
                        remoteCertificateEx,
                        _checkCertName,
                        _serverMode,
                        _hostName);
                }

                if (remoteCertValidationCallback != null)
                {
                    success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors);
                }
                else
                {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired)
                    {
                        success = true;
                    }
                    else
                    {
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                    }
                }

                if (Logging.On)
                {
                    if (sslPolicyErrors != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors);
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                        {
                            foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                            {
                                Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation);
                            }
                        }
                    }
                    if (success)
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid);
                        }
                        else
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors);
                        }
                    }
                    else
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid);
                        }
                    }
                }
                GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true)));
            }
            finally
            {
                // At least on Win2k server the chain is found to have dependencies on the original cert context.
                // So it should be closed first.
                if (chain != null)
                {
                    chain.Dispose();
                }

                if (remoteCertificateEx != null)
                {
                    remoteCertificateEx.Dispose();
                }
            }
            GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            return(success);
        }
Example #15
0
 internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback  certSelectionCallback, EncryptionPolicy encryptionPolicy, SSPIConfiguration config)
     : this(innerStream, certValidationCallback, certSelectionCallback, encryptionPolicy)
 {
     _Configuration = config;
 }
Example #16
0
        /*++
            VerifyRemoteCertificate - Validates the content of a Remote Certificate

            checkCRL if true, checks the certificate revocation list for validity.
            checkCertName, if true checks the CN field of the certificate
        --*/

        //This method validates a remote certificate.
        //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build
        //          A user callback has unique signature so it is safe to call it under permission assert.
        //
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback, ref ProtocolToken alertToken)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate");
            }

            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;

            // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true.
            bool success = false;
            X509Chain chain = null;
            X509Certificate2 remoteCertificateEx = null;

            try
            {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx = CertificateValidationPal.GetRemoteCertificate(_securityContext, out remoteCertificateStore);
                _isRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    if (GlobalLog.IsEnabled)
                    {
                        GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString());
                    }
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
                    }

                    sslPolicyErrors |= CertificateValidationPal.VerifyCertificateProperties(
                        chain,
                        remoteCertificateEx,
                        _checkCertName,
                        _serverMode,
                        _hostName);
                }

                if (remoteCertValidationCallback != null)
                {
                    success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors);
                }
                else
                {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired)
                    {
                        success = true;
                    }
                    else
                    {
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                    }
                }

                if (SecurityEventSource.Log.IsEnabled())
                {
                    LogCertificateValidation(remoteCertValidationCallback, sslPolicyErrors, success, chain);
                }

                if (GlobalLog.IsEnabled)
                {
                    GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true)));
                }

                if (!success)
                {
                    alertToken = CreateFatalHandshakeAlertToken(sslPolicyErrors, chain);
                }
            }
            finally
            {
                // At least on Win2k server the chain is found to have dependencies on the original cert context.
                // So it should be closed first.
                if (chain != null)
                {
                    chain.Dispose();
                }

                if (remoteCertificateEx != null)
                {
                    remoteCertificateEx.Dispose();
                }
            }

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Leave("SecureChannel#" + LoggingHash.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            }

            return success;
        }
Example #17
0
        private void LogCertificateValidation(RemoteCertValidationCallback remoteCertValidationCallback, SslPolicyErrors sslPolicyErrors, bool success, X509Chain chain)
        {
            if (sslPolicyErrors != SslPolicyErrors.None)
            {
                SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_has_errors);
                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                {
                    SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_not_available);
                }

                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                {
                    SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), SR.net_log_remote_cert_name_mismatch);
                }

                if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                {
                    string chainStatusString = "ChainStatus: ";
                    foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                    {
                        chainStatusString += "\t" + chainStatus.StatusInformation;
                    }
                    SecurityEventSource.Log.RemoteCertificateError(LoggingHash.HashInt(this), chainStatusString);
                }
            }

            if (success)
            {
                if (remoteCertValidationCallback != null)
                {
                    SecurityEventSource.Log.RemoteCertDeclaredValid(LoggingHash.HashInt(this));
                }
                else
                {
                    SecurityEventSource.Log.RemoteCertHasNoErrors(LoggingHash.HashInt(this));
                }
            }
            else
            {
                if (remoteCertValidationCallback != null)
                {
                    SecurityEventSource.Log.RemoteCertUserDeclaredInvalid(LoggingHash.HashInt(this));
                }
            }
        }
Example #18
0
        internal static SSPIInterface Create(string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, XX509CertificateCollection clientCertificates,
                                             bool remoteCertRequired, bool checkCertName, bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy,
                                             LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig)
        {
            if (userConfig.Settings != null && remoteValidationCallback != null)
            {
                throw new InvalidOperationException();
            }
            var context = userConfig.Provider.CreateTlsContext(
                hostname, serverMode, (TlsProtocols)protocolFlags, serverCertificate, clientCertificates,
                remoteCertRequired, checkCertName, checkCertRevocationStatus,
                (MonoEncryptionPolicy)encryptionPolicy, userConfig.Settings);

            return(new SSPIInterface(context, userConfig.EventSink));
        }
        private void ValidateCreateContext(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
        {
            ThrowIfExceptional();

            if (_context != null && _context.IsValidContext)
            {
                throw new InvalidOperationException(SR.net_auth_reauth);
            }

            if (_context != null && IsServer)
            {
                throw new InvalidOperationException(SR.net_auth_client_server);
            }

            if (sslClientAuthenticationOptions.TargetHost == null)
            {
                throw new ArgumentNullException(nameof(sslClientAuthenticationOptions.TargetHost));
            }

            _exception = null;
            try
            {
                _sslAuthenticationOptions = new SslAuthenticationOptions(sslClientAuthenticationOptions, remoteCallback, localCallback);
                if (_sslAuthenticationOptions.TargetHost.Length == 0)
                {
                    _sslAuthenticationOptions.TargetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
                }
                _context = new SecureChannel(_sslAuthenticationOptions);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
Example #20
0
        internal static RemoteCertificateValidationCallback InternalToPublic(string hostname, RemoteCertValidationCallback callback)
        {
            if (callback == null)
            {
                return(null);
            }

            return((s, c, ch, e) => callback(hostname, c, ch, e));
        }
Example #21
0
 //
 //  The public Client and Server classes enforce the parameters rules before
 //  calling into this .ctor.
 //
 internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy)
 {
 }
Example #22
0
        /*++
            VerifyRemoteCertificate - Validates the content of a Remote Certificate

            checkCRL if true, checks the certificate revocation list for validity.
            checkCertName, if true checks the CN field of the certificate
        --*/

        //This method validates a remote certificate.
        //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build
        //          A user callback has unique signature so it is safe to call it under permission assert.
        //
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate");
            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;

            // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true.
            bool success = false;
            X509Chain chain = null;
            X509Certificate2 remoteCertificateEx = null;

            try
            {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx = GetRemoteCertificate(out remoteCertificateStore);
                _isRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString());
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
                    }

                    if (!chain.Build(remoteCertificateEx)       // Build failed on handle or on policy.
                        && chain.SafeHandle.DangerousGetHandle() == IntPtr.Zero)   // Build failed to generate a valid handle.
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }

                    if (_checkCertName)
                    {
                        unsafe
                        {
                            uint status = 0;

                            var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA()
                            {
                                cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA>(),
                                dwAuthType = IsServer ? Interop.Crypt32.AuthType.AUTHTYPE_SERVER : Interop.Crypt32.AuthType.AUTHTYPE_CLIENT,
                                fdwChecks = 0,
                                pwszServerName = null
                            };

                            var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA()
                            {
                                cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_PARA>(),
                                dwFlags = 0,
                                pvExtraPolicyPara = &eppStruct
                            };

                            fixed (char* namePtr = _hostName)
                            {
                                eppStruct.pwszServerName = namePtr;
                                cppStruct.dwFlags |=
                                    (Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
                                     ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG);

                                SafeX509ChainHandle chainContext = chain.SafeHandle;
                                status = Verify(chainContext, ref cppStruct);
                                if (status == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
                                {
                                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                                }
                            }
                        }
                    }

                    X509ChainStatus[] chainStatusArray = chain.ChainStatus;
                    if (chainStatusArray != null && chainStatusArray.Length != 0)
                    {
                        sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
                    }
                }

                if (remoteCertValidationCallback != null)
                {
                    success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors);
                }
                else
                {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired)
                    {
                        success = true;
                    }
                    else
                    {
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                    }
                }

                if (Logging.On)
                {
                    if (sslPolicyErrors != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors);
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                        {
                            foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                            {
                                Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation);
                            }
                        }
                    }
                    if (success)
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid);
                        }
                        else
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors);
                        }
                    }
                    else
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid);
                        }
                    }
                }
                GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true)));
            }
            finally
            {
                // At least on Win2k server the chain is found to have dependencies on the original cert context.
                // So it should be closed first.
                if (chain != null)
                {
                    chain.Dispose();
                }

                if (remoteCertificateEx != null)
                {
                    remoteCertificateEx.Dispose();
                }
            }
            GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            return success;
        }
Example #23
0
        internal SecureChannel(string hostname, bool serverMode, SchProtocols protocolFlags, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertName,
            bool checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, LocalCertSelectionCallback certSelectionDelegate, RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration config)
        {
            GlobalLog.Enter("SecureChannel#" + ValidationHelper.HashString(this) + "::.ctor", "hostname:" + hostname + " #clientCertificates=" + ((clientCertificates == null) ? "0" : clientCertificates.Count.ToString(NumberFormatInfo.InvariantInfo)));
            if (Logging.On) Logging.PrintInfo(Logging.Web, this, ".ctor", "hostname=" + hostname + ", #clientCertificates=" + ((clientCertificates == null) ? "0" : clientCertificates.Count.ToString(NumberFormatInfo.InvariantInfo)) + ", encryptionPolicy=" + encryptionPolicy);
            m_SecModule = GlobalSSPI.Create(hostname, serverMode, protocolFlags, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, encryptionPolicy, certSelectionDelegate, remoteValidationCallback, config);

            m_Destination = hostname;

            GlobalLog.Assert(hostname != null, "SecureChannel#{0}::.ctor()|hostname == null", ValidationHelper.HashString(this));
            m_HostName = hostname;
            m_ServerMode = serverMode;

            if (serverMode)
                m_ProtocolFlags = (protocolFlags & SchProtocols.ServerMask);
            else
                m_ProtocolFlags = (protocolFlags & SchProtocols.ClientMask);

            m_ServerCertificate = serverCertificate;
            m_ClientCertificates = clientCertificates;
            m_RemoteCertRequired = remoteCertRequired;
            m_SecurityContext = null;
            m_CheckCertRevocation = checkCertRevocationStatus;
            m_CheckCertName = checkCertName;
            m_CertSelectionDelegate = certSelectionDelegate;
            m_RefreshCredentialNeeded = true;
            m_EncryptionPolicy = encryptionPolicy;
            GlobalLog.Leave("SecureChannel#" + ValidationHelper.HashString(this) + "::.ctor");
        }
Example #24
0
        internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback?localCallback)
        {
            Debug.Assert(sslClientAuthenticationOptions.TargetHost != null);

            // Common options.
            AllowRenegotiation     = sslClientAuthenticationOptions.AllowRenegotiation;
            ApplicationProtocols   = sslClientAuthenticationOptions.ApplicationProtocols;
            CertValidationDelegate = remoteCallback;
            CheckCertName          = true;
            EnabledSslProtocols    = FilterOutIncompatibleSslProtocols(sslClientAuthenticationOptions.EnabledSslProtocols);
            EncryptionPolicy       = sslClientAuthenticationOptions.EncryptionPolicy;
            IsServer           = false;
            RemoteCertRequired = true;
            TargetHost         = sslClientAuthenticationOptions.TargetHost !;

            // Client specific options.
            CertSelectionDelegate          = localCallback;
            CertificateRevocationCheckMode = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
            ClientCertificates             = sslClientAuthenticationOptions.ClientCertificates;
            CipherSuitesPolicy             = sslClientAuthenticationOptions.CipherSuitesPolicy;
        }
Example #25
0
 //
 // SSL related properties
 //
 internal void SetCertValidationDelegate(RemoteCertValidationCallback certValidationCallback)
 {
     _certValidationDelegate = certValidationCallback;
 }
Example #26
0
        /*++
            VerifyRemoteCertificate - Validates the content of a Remote Certificate

            checkCRL if true, checks the certificate revocation list for validity.
            checkCertName, if true checks the CN field of the certificate
        --*/

        //This method validates a remote certificate.
        //SECURITY: The scenario is allowed in semitrust StorePermission is asserted for Chain.Build
        //          A user callback has unique signature so it is safe to call it under permission assert.
        //
        internal bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate");
            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;

            // We don't catch exceptions in this method, so it's safe for "accepted" be initialized with true.
            bool success = false;
            X509Chain chain = null;
            X509Certificate2 remoteCertificateEx = null;

            try
            {
                X509Certificate2Collection remoteCertificateStore;
                remoteCertificateEx = CertWrapper.GetRemoteCertificate(_securityContext, out remoteCertificateStore);
                _isRemoteCertificateAvailable = remoteCertificateEx != null;

                if (remoteCertificateEx == null)
                {
                    GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate (no remote cert)", (!_remoteCertRequired).ToString());
                    sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain();
                    chain.ChainPolicy.RevocationMode = _checkCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
                    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                    if (remoteCertificateStore != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
                    }

                    // Don't call chain.Build here in the common code, because the Windows version
                    // is potentially going to check for GetLastWin32Error, and that call needs to be
                    // guaranteed to be right after the call to chain.Build.

                    sslPolicyErrors |= CertWrapper.VerifyCertificateProperties(
                        chain,
                        remoteCertificateEx,
                        _checkCertName,
                        _serverMode,
                        _hostName);
                }

                if (remoteCertValidationCallback != null)
                {
                    success = remoteCertValidationCallback(_hostName, remoteCertificateEx, chain, sslPolicyErrors);
                }
                else
                {
                    if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNotAvailable && !_remoteCertRequired)
                    {
                        success = true;
                    }
                    else
                    {
                        success = (sslPolicyErrors == SslPolicyErrors.None);
                    }
                }

                if (Logging.On)
                {
                    if (sslPolicyErrors != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_errors);
                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_not_available);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + SR.net_log_remote_cert_name_mismatch);
                        }

                        if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                        {
                            foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                            {
                                Logging.PrintInfo(Logging.Web, this, "\t" + chainStatus.StatusInformation);
                            }
                        }
                    }
                    if (success)
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_valid);
                        }
                        else
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_has_no_errors);
                        }
                    }
                    else
                    {
                        if (remoteCertValidationCallback != null)
                        {
                            Logging.PrintInfo(Logging.Web, this, SR.net_log_remote_cert_user_declared_invalid);
                        }
                    }
                }
                GlobalLog.Print("Cert Validation, remote cert = " + (remoteCertificateEx == null ? "<null>" : remoteCertificateEx.ToString(true)));
            }
            finally
            {
                // At least on Win2k server the chain is found to have dependencies on the original cert context.
                // So it should be closed first.
                if (chain != null)
                {
                    chain.Dispose();
                }

                if (remoteCertificateEx != null)
                {
                    remoteCertificateEx.Dispose();
                }
            }
            GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::VerifyRemoteCertificate", success.ToString());
            return success;
        }     
Example #27
0
 //
 //  The public Client and Server classes enforce the parameters rules before
 //  calling into this .ctor.
 //
 internal SslState(Stream innerStream, RemoteCertValidationCallback certValidationCallback, LocalCertSelectionCallback certSelectionCallback, EncryptionPolicy encryptionPolicy)
 {
 }
        internal SslAuthenticationOptions(SslClientAuthenticationOptions sslClientAuthenticationOptions, RemoteCertValidationCallback remoteCallback, LocalCertSelectionCallback localCallback)
        {
            // Common options.
            AllowRenegotiation     = sslClientAuthenticationOptions.AllowRenegotiation;
            ApplicationProtocols   = sslClientAuthenticationOptions.ApplicationProtocols;
            CertValidationDelegate = remoteCallback;
            CheckCertName          = true;
            EnabledSslProtocols    = sslClientAuthenticationOptions.EnabledSslProtocols;
            EncryptionPolicy       = sslClientAuthenticationOptions.EncryptionPolicy;
            IsServer           = false;
            RemoteCertRequired = true;
            RemoteCertificateValidationCallback = sslClientAuthenticationOptions.RemoteCertificateValidationCallback;
            TargetHost = sslClientAuthenticationOptions.TargetHost;

            // Client specific options.
            CertSelectionDelegate             = localCallback;
            CertificateRevocationCheckMode    = sslClientAuthenticationOptions.CertificateRevocationCheckMode;
            ClientCertificates                = sslClientAuthenticationOptions.ClientCertificates;
            LocalCertificateSelectionCallback = sslClientAuthenticationOptions.LocalCertificateSelectionCallback;
        }