System.Net.Security.SecureChannel.GenerateToken C# (CSharp) Method

GenerateToken() private method

private GenerateToken ( byte input, int offset, int count, byte &output ) : SecurityStatusPal
input byte
offset int
count int
output byte
return SecurityStatusPal
        private SecurityStatusPal GenerateToken(byte[] input, int offset, int count, ref byte[] output)
        {
#if TRACE_VERBOSE
            if (NetEventSource.IsEnabled) NetEventSource.Enter(this, $"_refreshCredentialNeeded = {_refreshCredentialNeeded}");
#endif

            if (offset < 0 || offset > (input == null ? 0 : input.Length))
            {
                NetEventSource.Fail(this, "Argument 'offset' out of range.");
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            if (count < 0 || count > (input == null ? 0 : input.Length - offset))
            {
                NetEventSource.Fail(this, "Argument 'count' out of range.");
                throw new ArgumentOutOfRangeException(nameof(count));
            }

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

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

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

            SecurityStatusPal status = default(SecurityStatusPal);

            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)
                    {
                        status = SslStreamPal.AcceptSecurityContext(
                                      ref _credentialsHandle,
                                      ref _securityContext,
                                      incomingSecurity,
                                      outgoingSecurity,
                                      _remoteCertRequired);
                    }
                    else
                    {
                        if (incomingSecurity == null)
                        {
                            status = SslStreamPal.InitializeSecurityContext(
                                           ref _credentialsHandle,
                                           ref _securityContext,
                                           _destination,
                                           incomingSecurity,
                                           outgoingSecurity);
                        }
                        else
                        {
                            status = SslStreamPal.InitializeSecurityContext(
                                           _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;
            
            return status;
        }