示例#1
0
        public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteContext context, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, bool remoteCertRequired)
        {
            Interop.SspiCli.ContextFlags unusedAttributes = default(Interop.SspiCli.ContextFlags);

            int errorCode = SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPISecureChannel,
                ref credentialsHandle,
                ref context,
                ServerRequiredFlags | (remoteCertRequired ? Interop.SspiCli.ContextFlags.MutualAuth : Interop.SspiCli.ContextFlags.Zero),
                Interop.SspiCli.Endianness.SECURITY_NATIVE_DREP,
                inputBuffer,
                outputBuffer,
                ref unusedAttributes);

            return(SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode));
        }
示例#2
0
        internal static SecurityStatusPal AcceptSecurityContext(
            SafeFreeCredentials?credentialsHandle,
            ref SafeDeleteContext?securityContext,
            ContextFlagsPal requestedContextFlags,
            byte[]?incomingBlob,
            ChannelBinding?channelBinding,
            ref byte[]?resultBlob,
            ref ContextFlagsPal contextFlags)
        {
            InputSecurityBuffers inputBuffers = default;

            if (incomingBlob != null)
            {
                inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN));
            }

            if (channelBinding != null)
            {
                inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding));
            }

            var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN);

            Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero;
            // There is only one SafeDeleteContext type on Windows which is SafeDeleteSslContext so this cast is safe.
            SafeDeleteSslContext?sslContext = (SafeDeleteSslContext?)securityContext;

            Interop.SECURITY_STATUS winStatus = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPIAuth,
                credentialsHandle,
                ref sslContext,
                ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags),
                Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP,
                inputBuffers,
                ref outSecurityBuffer,
                ref outContextFlags);

            resultBlob      = outSecurityBuffer.token;
            securityContext = sslContext;
            contextFlags    = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags);
            return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus));
        }
        internal static SecurityStatusPal AcceptSecurityContext(
            SafeFreeCredentials credentialsHandle,
            ref SafeDeleteContext securityContext,
            ContextFlagsPal requestedContextFlags,
            SecurityBuffer[] inSecurityBufferArray,
            SecurityBuffer outSecurityBuffer,
            ref ContextFlagsPal contextFlags)
        {
            Interop.SspiCli.ContextFlags outContextFlags = Interop.SspiCli.ContextFlags.Zero;
            Interop.SECURITY_STATUS      winStatus       = (Interop.SECURITY_STATUS)SSPIWrapper.AcceptSecurityContext(
                GlobalSSPI.SSPIAuth,
                credentialsHandle,
                ref securityContext,
                ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags),
                Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP,
                inSecurityBufferArray,
                outSecurityBuffer,
                ref outContextFlags);

            contextFlags = ContextFlagsAdapterPal.GetContextFlagsPalFromInterop(outContextFlags);
            return(SecurityStatusAdapterPal.GetSecurityStatusPalFromInterop(winStatus));
        }
示例#4
0
        private SecurityStatus GenerateToken(byte[] input, int offset, int count, ref byte[] output)
        {
            if ((offset < 0) || (offset > ((input == null) ? 0 : input.Length)))
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if ((count < 0) || (count > ((input == null) ? 0 : (input.Length - offset))))
            {
                throw new ArgumentOutOfRangeException("count");
            }
            SecurityBuffer inputBuffer = null;

            SecurityBuffer[] inputBuffers = null;
            if (input != null)
            {
                inputBuffer  = new SecurityBuffer(input, offset, count, BufferType.Token);
                inputBuffers = new SecurityBuffer[] { inputBuffer, new SecurityBuffer(null, 0, 0, BufferType.Empty) };
            }
            SecurityBuffer outputBuffer = new SecurityBuffer(null, BufferType.Token);
            int            num          = 0;
            bool           flag         = false;

            byte[] thumbPrint = null;
            try
            {
                do
                {
                    thumbPrint = null;
                    if (this.m_RefreshCredentialNeeded)
                    {
                        flag = this.m_ServerMode ? this.AcquireServerCredentials(ref thumbPrint) : this.AcquireClientCredentials(ref thumbPrint);
                    }
                    if (this.m_ServerMode)
                    {
                        num = SSPIWrapper.AcceptSecurityContext(GlobalSSPI.SSPISecureChannel, ref this.m_CredentialsHandle, ref this.m_SecurityContext, (ContextFlags.AcceptStream | ContextFlags.AllocateMemory | ContextFlags.Confidentiality | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect) | (this.m_RemoteCertRequired ? ContextFlags.MutualAuth : ContextFlags.Zero), Endianness.Native, inputBuffer, outputBuffer, ref this.m_Attributes);
                    }
                    else if (inputBuffer == null)
                    {
                        num = SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPISecureChannel, ref this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_Destination, ContextFlags.AcceptIdentify | ContextFlags.AllocateMemory | ContextFlags.Confidentiality | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect, Endianness.Native, inputBuffer, outputBuffer, ref this.m_Attributes);
                    }
                    else
                    {
                        num = SSPIWrapper.InitializeSecurityContext(GlobalSSPI.SSPISecureChannel, this.m_CredentialsHandle, ref this.m_SecurityContext, this.m_Destination, ContextFlags.AcceptIdentify | ContextFlags.AllocateMemory | ContextFlags.Confidentiality | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect, Endianness.Native, inputBuffers, outputBuffer, ref this.m_Attributes);
                    }
                }while (flag && (this.m_CredentialsHandle == null));
            }
            finally
            {
                if (this.m_RefreshCredentialNeeded)
                {
                    this.m_RefreshCredentialNeeded = false;
                    if (this.m_CredentialsHandle != null)
                    {
                        this.m_CredentialsHandle.Close();
                    }
                    if ((!flag && (this.m_SecurityContext != null)) && (!this.m_SecurityContext.IsInvalid && !this.m_CredentialsHandle.IsInvalid))
                    {
                        SslSessionsCache.CacheCredential(this.m_CredentialsHandle, thumbPrint, this.m_ProtocolFlags, this.m_EncryptionPolicy);
                    }
                }
            }
            output = outputBuffer.token;
            return((SecurityStatus)num);
        }
示例#5
0
        /*++
         *  GenerateToken - Called after each successive state
         *  in the Client - Server handshake.  This function
         *  generates a set of bytes that will be sent next to
         *  the server.  The server responds, each response,
         *  is pass then into this function, again, and the cycle
         *  repeats until successful connection, or failure.
         *
         *  Input:
         *      input  - bytes from the wire
         *      output - ref to byte [], what we will send to the
         *          server in response
         *  Return:
         *      errorCode - an SSPI error code
         * --*/
        private SecurityStatus GenerateToken(byte[] input, int offset, int count, ref byte[] output)
        {
#if TRACE_VERBOSE
            GlobalLog.Enter("SecureChannel#" + Logging.HashString(this) + "::GenerateToken, _refreshCredentialNeeded = " + _refreshCredentialNeeded);
#endif

            if (offset < 0 || offset > (input == null ? 0 : input.Length))
            {
                GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::GenerateToken", "Argument 'offset' out of range.");
                throw new ArgumentOutOfRangeException("offset");
            }

            if (count < 0 || count > (input == null ? 0 : input.Length - offset))
            {
                GlobalLog.Assert(false, "SecureChannel#" + Logging.HashString(this) + "::GenerateToken", "Argument 'count' out of range.");
                throw new ArgumentOutOfRangeException("count");
            }

            SecurityBuffer   incomingSecurity        = null;
            SecurityBuffer[] incomingSecurityBuffers = null;

            if (input != null)
            {
                incomingSecurity        = new SecurityBuffer(input, offset, count, SecurityBufferType.Token);
                incomingSecurityBuffers = new SecurityBuffer[]
                {
                    incomingSecurity,
                    new SecurityBuffer(null, 0, 0, SecurityBufferType.Empty)
                };
            }

            SecurityBuffer outgoingSecurity = new SecurityBuffer(null, SecurityBufferType.Token);

            SecurityStatus errorCode = 0;

            bool   cachedCreds = false;
            byte[] thumbPrint  = null;

            //
            // Looping through ASC or ISC with potentially cached credential that could have been
            // already disposed from a different thread before ISC or ASC dir increment a cred ref count.
            //
            try
            {
                do
                {
                    thumbPrint = null;
                    if (_refreshCredentialNeeded)
                    {
                        cachedCreds = _serverMode
                                        ? AcquireServerCredentials(ref thumbPrint)
                                        : AcquireClientCredentials(ref thumbPrint);
                    }

                    if (_serverMode)
                    {
                        errorCode = SSPIWrapper.AcceptSecurityContext(
                            GlobalSSPI.SSPISecureChannel,
                            ref _credentialsHandle,
                            ref _securityContext,
                            incomingSecurity,
                            outgoingSecurity,
                            _remoteCertRequired
                            );
                    }
                    else
                    {
                        if (incomingSecurity == null)
                        {
                            errorCode = SSPIWrapper.InitializeSecurityContext(
                                GlobalSSPI.SSPISecureChannel,
                                ref _credentialsHandle,
                                ref _securityContext,
                                _destination,
                                incomingSecurity,
                                outgoingSecurity
                                );
                        }
                        else
                        {
                            errorCode = SSPIWrapper.InitializeSecurityContext(
                                GlobalSSPI.SSPISecureChannel,
                                _credentialsHandle,
                                ref _securityContext,
                                _destination,
                                incomingSecurityBuffers,
                                outgoingSecurity
                                );
                        }
                    }
                } while (cachedCreds && _credentialsHandle == null);
            }
            finally
            {
                if (_refreshCredentialNeeded)
                {
                    _refreshCredentialNeeded = false;

                    //
                    // Assuming the ISC or ASC has referenced the credential,
                    // we want to call dispose so to decrement the effective ref count.
                    //
                    if (_credentialsHandle != null)
                    {
                        _credentialsHandle.Dispose();
                    }

                    //
                    // This call may bump up the credential reference count further.
                    // Note that thumbPrint is retrieved from a safe cert object that was possible cloned from the user passed cert.
                    //
                    if (!cachedCreds && _securityContext != null && !_securityContext.IsInvalid && _credentialsHandle != null && !_credentialsHandle.IsInvalid)
                    {
                        SslSessionsCache.CacheCredential(_credentialsHandle, thumbPrint, _sslProtocols, _serverMode, _encryptionPolicy);
                    }
                }
            }

            output = outgoingSecurity.token;

#if TRACE_VERBOSE
            GlobalLog.Leave("SecureChannel#" + Logging.HashString(this) + "::GenerateToken()", Interop.MapSecurityStatus((uint)errorCode));
#endif
            return((SecurityStatus)errorCode);
        }