Пример #1
0
        private void ValidateCreateContext(SslAuthenticationOptions sslAuthenticationOptions)
        {
            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);
            }

            _exception = null;
            _sslAuthenticationOptions = sslAuthenticationOptions;

            try
            {
                _context = new SecureChannel(_sslAuthenticationOptions);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
Пример #2
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);
            }
        }
Пример #3
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);
                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);
            }
        }
Пример #4
0
 public static SecurityStatusPal Renegotiate(
     SecureChannel secureChannel,
     ref SafeFreeCredentials?credentialsHandle,
     ref SafeDeleteSslContext?context,
     SslAuthenticationOptions sslAuthenticationOptions,
     out byte[]?outputBuffer)
 {
     throw new PlatformNotSupportedException();
 }
Пример #5
0
 public static SecurityStatusPal AcceptSecurityContext(
     SecureChannel secureChannel,
     ref SafeFreeCredentials credential,
     ref SafeDeleteSslContext?context,
     ReadOnlySpan <byte> inputBuffer,
     ref byte[]?outputBuffer,
     SslAuthenticationOptions sslAuthenticationOptions)
 {
     return(HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions));
 }
Пример #6
0
 public static SecurityStatusPal InitializeSecurityContext(
     SecureChannel secureChannel,
     ref SafeFreeCredentials?credential,
     ref SafeDeleteSslContext?context,
     string?targetName,
     ReadOnlySpan <byte> inputBuffer,
     ref byte[]?outputBuffer,
     SslAuthenticationOptions sslAuthenticationOptions)
 {
     return(HandshakeInternal(secureChannel, credential !, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions));
 }
Пример #7
0
 internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus, bool checkCertName)
 {
     if ((this._Exception != null) && !this._CanRetryAuthentication)
     {
         throw this._Exception;
     }
     if ((this.Context != null) && this.Context.IsValidContext)
     {
         throw new InvalidOperationException(SR.GetString("net_auth_reauth"));
     }
     if ((this.Context != null) && (this.IsServer != isServer))
     {
         throw new InvalidOperationException(SR.GetString("net_auth_client_server"));
     }
     if (targetHost == null)
     {
         throw new ArgumentNullException("targetHost");
     }
     if (isServer)
     {
         enabledSslProtocols &= 0x40000055;
         if (serverCertificate == null)
         {
             throw new ArgumentNullException("serverCertificate");
         }
     }
     else
     {
         enabledSslProtocols &= -2147483478;
     }
     if (enabledSslProtocols == SslProtocols.None)
     {
         throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SslProtocolType" }), "sslProtocolType");
     }
     if (clientCertificates == null)
     {
         clientCertificates = new X509CertificateCollection();
     }
     if (targetHost.Length == 0)
     {
         targetHost = "?" + Interlocked.Increment(ref UniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
     }
     this._Exception = null;
     try
     {
         this._Context = new SecureChannel(targetHost, isServer, (SchProtocols)enabledSslProtocols, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, this._EncryptionPolicy, this._CertSelectionDelegate);
     }
     catch (Win32Exception exception)
     {
         throw new AuthenticationException(SR.GetString("net_auth_SSPI"), exception);
     }
 }
Пример #8
0
        internal SslAuthenticationOptions(SslServerAuthenticationOptions sslServerAuthenticationOptions)
        {
            // Common options.
            AllowRenegotiation   = sslServerAuthenticationOptions.AllowRenegotiation;
            ApplicationProtocols = sslServerAuthenticationOptions.ApplicationProtocols;
            CheckCertName        = false;
            EnabledSslProtocols  = FilterOutIncompatibleSslProtocols(sslServerAuthenticationOptions.EnabledSslProtocols);
            EncryptionPolicy     = sslServerAuthenticationOptions.EncryptionPolicy;
            IsServer             = true;
            RemoteCertRequired   = sslServerAuthenticationOptions.ClientCertificateRequired;
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(this, $"Server RemoteCertRequired: {RemoteCertRequired}.");
            }
            TargetHost = string.Empty;

            // Server specific options.
            CipherSuitesPolicy             = sslServerAuthenticationOptions.CipherSuitesPolicy;
            CertificateRevocationCheckMode = sslServerAuthenticationOptions.CertificateRevocationCheckMode;

            if (sslServerAuthenticationOptions.ServerCertificateContext != null)
            {
                CertificateContext = sslServerAuthenticationOptions.ServerCertificateContext;
            }
            else if (sslServerAuthenticationOptions.ServerCertificate != null)
            {
                X509Certificate2?certificateWithKey = sslServerAuthenticationOptions.ServerCertificate as X509Certificate2;

                if (certificateWithKey != null && certificateWithKey.HasPrivateKey)
                {
                    // given cert is X509Certificate2 with key. We can use it directly.
                    CertificateContext = SslStreamCertificateContext.Create(certificateWithKey, null);
                }
                else
                {
                    // This is legacy fix-up. If the Certificate did not have key, we will search stores and we
                    // will try to find one with matching hash.
                    certificateWithKey = SecureChannel.FindCertificateWithPrivateKey(this, true, sslServerAuthenticationOptions.ServerCertificate);
                    if (certificateWithKey == null)
                    {
                        throw new AuthenticationException(SR.net_ssl_io_no_server_cert);
                    }

                    CertificateContext = SslStreamCertificateContext.Create(certificateWithKey);
                }
            }

            if (sslServerAuthenticationOptions.RemoteCertificateValidationCallback != null)
            {
                CertValidationDelegate = sslServerAuthenticationOptions.RemoteCertificateValidationCallback;
            }
        }
Пример #9
0
        public static SecurityStatusPal AcceptSecurityContext(
            SecureChannel secureChannel,
            ref SafeFreeCredentials?credentialsHandle,
            ref SafeDeleteSslContext?context,
            ReadOnlySpan <byte> inputBuffer,
            ref byte[]?outputBuffer,
            SslAuthenticationOptions sslAuthenticationOptions)
        {
            Interop.SspiCli.ContextFlags unusedAttributes = default;

            InputSecurityBuffers inputBuffers = default;

            inputBuffers.SetNextBuffer(new InputSecurityBuffer(inputBuffer, SecurityBufferType.SECBUFFER_TOKEN));
            inputBuffers.SetNextBuffer(new InputSecurityBuffer(default, SecurityBufferType.SECBUFFER_EMPTY));
Пример #10
0
        private static SecurityStatusPal HandshakeInternal(
            SecureChannel secureChannel,
            SafeFreeCredentials credential,
            ref SafeDeleteSslContext?context,
            ReadOnlySpan <byte> inputBuffer,
            ref byte[]?outputBuffer,
            SslAuthenticationOptions sslAuthenticationOptions)
        {
            Debug.Assert(!credential.IsInvalid);

            try
            {
                SafeDeleteSslContext?sslContext = ((SafeDeleteSslContext?)context);

                if ((null == context) || context.IsInvalid)
                {
                    sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials) !, sslAuthenticationOptions);
                    context    = sslContext;
                }

                if (inputBuffer.Length > 0)
                {
                    sslContext !.Write(inputBuffer);
                }

                SafeSslHandle     sslHandle = sslContext !.SslContext;
                SecurityStatusPal status    = PerformHandshake(sslHandle);
                if (status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded)
                {
                    X509Certificate2?clientCertificate = secureChannel.SelectClientCertificate(out _);
                    if (clientCertificate != null)
                    {
                        sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate);
                        SafeDeleteSslContext.SetCertificate(sslContext.SslContext, sslAuthenticationOptions.CertificateContext);
                    }

                    // We either got certificate or we can proceed without it. It is up to the server to decide if either is OK.
                    status = PerformHandshake(sslHandle);
                }

                outputBuffer = sslContext.ReadPendingWrites();
                return(status);
            }
            catch (Exception exc)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc));
            }
        }
Пример #11
0
        internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus, bool checkCertName)
        {
            //
            // We don't support SSL alerts right now, hence any exception is fatal and cannot be retried.
            //
            if (_exception != null)
            {
                _exception.Throw();
            }

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

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

            if (targetHost == null)
            {
                throw new ArgumentNullException(nameof(targetHost));
            }

            if (isServer && serverCertificate == null)
            {
                throw new ArgumentNullException(nameof(serverCertificate));
            }

            if ((int)enabledSslProtocols == 0)
            {
                throw new ArgumentException(SR.Format(SR.net_invalid_enum, "SslProtocolType"), "sslProtocolType");
            }

            if (clientCertificates == null)
            {
                clientCertificates = new X509CertificateCollection();
            }

            if (targetHost.Length == 0)
            {
                targetHost = "?" + Interlocked.Increment(ref s_uniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
            }

            _exception = null;
            try
            {
                _context = new SecureChannel(targetHost, isServer, enabledSslProtocols, serverCertificate, clientCertificates, remoteCertRequired,
                                                                 checkCertName, checkCertRevocationStatus, _encryptionPolicy, _certSelectionDelegate);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.net_auth_SSPI, e);
            }
        }
Пример #12
0
        internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus, bool checkCertName)
        {

            //
            // We don;t support SSL alerts right now, hence any exception is fatal and cannot be retried
            // Consider: make use if SSL alerts to re-[....] SslStream on both sides for retrying.
            //
            if (_Exception != null && !_CanRetryAuthentication) {
                throw _Exception;
            }

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

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

            if (targetHost == null) {
                throw new ArgumentNullException("targetHost");
            }


            if (isServer ) {
                enabledSslProtocols &= (SslProtocols)SchProtocols.ServerMask;
                if (serverCertificate == null)
                    throw new ArgumentNullException("serverCertificate");
            }
            else {
                enabledSslProtocols &= (SslProtocols)SchProtocols.ClientMask;
            }

            if ((int)enabledSslProtocols == 0) {
                throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SslProtocolType"), "sslProtocolType");
            }

            if (clientCertificates == null) {
                clientCertificates = new X509CertificateCollection();
            }

            if (targetHost.Length == 0) {
               targetHost = "?" + Interlocked.Increment(ref UniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
            }

            _Exception = null;
            try {
                _Context = new SecureChannel(targetHost, isServer, (SchProtocols)((int)enabledSslProtocols), serverCertificate, clientCertificates, remoteCertRequired,
                                                               checkCertName, checkCertRevocationStatus, _EncryptionPolicy, _CertSelectionDelegate);
            }
            catch (Win32Exception e) {
                throw new AuthenticationException(SR.GetString(SR.net_auth_SSPI), e);
            }

        }
Пример #13
0
        private static SecurityStatusPal HandshakeInternal(
            SecureChannel secureChannel,
            SafeFreeCredentials credential,
            ref SafeDeleteSslContext?context,
            ReadOnlySpan <byte> inputBuffer,
            ref byte[]?outputBuffer,
            SslAuthenticationOptions sslAuthenticationOptions)
        {
            Debug.Assert(!credential.IsInvalid);

            try
            {
                SafeDeleteSslContext?sslContext = ((SafeDeleteSslContext?)context);

                if ((null == context) || context.IsInvalid)
                {
                    sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials) !, sslAuthenticationOptions);
                    context    = sslContext;

                    if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer)
                    {
                        Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost);
                    }

                    if (sslAuthenticationOptions.CertificateContext == null && sslAuthenticationOptions.CertSelectionDelegate != null)
                    {
                        // certificate was not provided but there is user callback. We can break handshake if server asks for certificate
                        // and we can try to get it based on remote certificate and trusted issuers.
                        Interop.AppleCrypto.SslBreakOnCertRequested(sslContext.SslContext, true);
                    }

                    if (sslAuthenticationOptions.IsServer && sslAuthenticationOptions.RemoteCertRequired)
                    {
                        Interop.AppleCrypto.SslSetAcceptClientCert(sslContext.SslContext);
                    }
                }

                if (inputBuffer.Length > 0)
                {
                    sslContext !.Write(inputBuffer);
                }

                SafeSslHandle     sslHandle = sslContext !.SslContext;
                SecurityStatusPal status    = PerformHandshake(sslHandle);
                if (status.ErrorCode == SecurityStatusPalErrorCode.CredentialsNeeded)
                {
                    X509Certificate2?clientCertificate = secureChannel.SelectClientCertificate(out _);
                    if (clientCertificate != null)
                    {
                        sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(clientCertificate);
                        SafeDeleteSslContext.SetCertificate(sslContext.SslContext, sslAuthenticationOptions.CertificateContext);
                    }

                    // We either got certificate or we can proceed without it. It is up to the server to decide if either is OK.
                    status = PerformHandshake(sslHandle);
                }

                outputBuffer = sslContext.ReadPendingWrites();
                return(status);
            }
            catch (Exception exc)
            {
                return(new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exc));
            }
        }
 internal void ValidateCreateContext(bool isServer, string targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, bool remoteCertRequired, bool checkCertRevocationStatus, bool checkCertName)
 {
     if ((this._Exception != null) && !this._CanRetryAuthentication)
     {
         throw this._Exception;
     }
     if ((this.Context != null) && this.Context.IsValidContext)
     {
         throw new InvalidOperationException(SR.GetString("net_auth_reauth"));
     }
     if ((this.Context != null) && (this.IsServer != isServer))
     {
         throw new InvalidOperationException(SR.GetString("net_auth_client_server"));
     }
     if (targetHost == null)
     {
         throw new ArgumentNullException("targetHost");
     }
     if (isServer)
     {
         enabledSslProtocols &= 0x40000055;
         if (serverCertificate == null)
         {
             throw new ArgumentNullException("serverCertificate");
         }
     }
     else
     {
         enabledSslProtocols &= -2147483478;
     }
     if (enabledSslProtocols == SslProtocols.None)
     {
         throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SslProtocolType" }), "sslProtocolType");
     }
     if (clientCertificates == null)
     {
         clientCertificates = new X509CertificateCollection();
     }
     if (targetHost.Length == 0)
     {
         targetHost = "?" + Interlocked.Increment(ref UniqueNameInteger).ToString(NumberFormatInfo.InvariantInfo);
     }
     this._Exception = null;
     try
     {
         this._Context = new SecureChannel(targetHost, isServer, (SchProtocols) enabledSslProtocols, serverCertificate, clientCertificates, remoteCertRequired, checkCertName, checkCertRevocationStatus, this._EncryptionPolicy, this._CertSelectionDelegate);
     }
     catch (Win32Exception exception)
     {
         throw new AuthenticationException(SR.GetString("net_auth_SSPI"), exception);
     }
 }