windowssocketswindows-server-2012-r2security-contextschannel

InitializeSecurityContext (Schannel) not changing BufferType


So i have following code:

SecBuffer input_buffers[2];
SecBuffer output_buffers[2];
ULONG context_attributes;

/* we need to try and perform the second (next) step of the init */
input_buffers[0].cbBuffer = tls_io_instance->received_byte_count;
input_buffers[0].BufferType = SECBUFFER_TOKEN;
input_buffers[0].pvBuffer = (void*)tls_io_instance->received_bytes;
input_buffers[1].cbBuffer = 0;
input_buffers[1].BufferType = SECBUFFER_EMPTY;
input_buffers[1].pvBuffer = 0;

SecBufferDesc input_buffers_desc;
input_buffers_desc.cBuffers = 2;
input_buffers_desc.pBuffers = input_buffers;
input_buffers_desc.ulVersion = SECBUFFER_VERSION;

output_buffers[0].cbBuffer = 0;
output_buffers[0].BufferType = SECBUFFER_TOKEN;
output_buffers[0].pvBuffer = NULL;
output_buffers[1].cbBuffer = 0;
output_buffers[1].BufferType = SECBUFFER_EMPTY;
output_buffers[1].pvBuffer = 0;

SecBufferDesc output_buffers_desc;
output_buffers_desc.cBuffers = 2;
output_buffers_desc.pBuffers = output_buffers;
output_buffers_desc.ulVersion = SECBUFFER_VERSION;

unsigned long flags = ISC_REQ_EXTENDED_ERROR | ISC_REQ_STREAM | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_USE_SUPPLIED_CREDS;
SECURITY_STATUS status = InitializeSecurityContext(&tls_io_instance->credential_handle,
                        &tls_io_instance->security_context, (SEC_CHAR*)tls_io_instance->host_name, flags, 0, 0, 
                        &input_buffers_desc, 0,
                        &tls_io_instance->security_context, &output_buffers_desc, &context_attributes, NULL);

Problem is, that after this code executes on Windows 8.1 or Windows 10 platform, input_buffers[1].BufferType is set to 4. And if it is executed on Windows Server 2012 R2, input_buffers[1].BufferType stays 0 (SECBUFFER_MISSING) and i end up with error. Does anyone know why InitializeSecurityContext (Schannel) function is not changing the type of input_buffers[1] on Windows Server?

I really appreciate any help you can provide.

Edit 1 status returned is same on both platforms (-2146893032), just on Win 8.1/10 function changes input_buffers[1].BufferType to 4.

Edit 2 On Win 8.1/ 10 it goes in else branch of this case option, and in Win Server 2012 R2 it goes into if branch.. On all platforms status is set to SEC_E_INCOMPLETE_MESSAGE (-2146893032)

   switch (status)
            {
            case SEC_E_INCOMPLETE_MESSAGE:
                if (input_buffers[1].BufferType != SECBUFFER_MISSING)
                {
                    tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
                    if (tls_io_instance->on_io_open_complete != NULL)
                    {
                        tls_io_instance->on_io_open_complete(tls_io_instance->open_callback_context, IO_OPEN_ERROR);
                    }
                }
                else
                {
                    tls_io_instance->needed_bytes = input_buffers[1].cbBuffer;
                    tls_io_instance->consumed_bytes += tls_io_instance->needed_bytes;
                    if (resize_receive_buffer(tls_io_instance, tls_io_instance->received_byte_count + tls_io_instance->needed_bytes) != 0)
                    {
                        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
                        if (tls_io_instance->on_io_open_complete != NULL)
                        {
                            tls_io_instance->on_io_open_complete(tls_io_instance->open_callback_context, IO_OPEN_ERROR);
                        }
                    }
                }

Solution

  • Ok so i contacted creators and it appears as this was a bug in their utility library code, they fixed it in Developer branch of utility library and they are testing it. Thank you all for replies !