secur32: Properly handle NULL pInput argument for DTLS contexts in schan_InitializeSecurityContextW.
When a NULL pInput argument is passed into InitializeSecurityContextW for an existing DTLS context, we need to retransmit the last handshake packet. Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
795d3e2cb5
commit
290cd6769f
|
@ -704,7 +704,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
struct schan_context *ctx;
|
||||
struct schan_buffers *out_buffers;
|
||||
struct schan_credentials *cred;
|
||||
SIZE_T expected_size = ~0UL;
|
||||
SIZE_T expected_size = 0;
|
||||
SECURITY_STATUS ret;
|
||||
SecBuffer *buffer;
|
||||
SecBuffer alloc_buffer = { 0 };
|
||||
|
@ -823,31 +823,34 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
unsigned char *ptr;
|
||||
|
||||
if (!(ctx = schan_get_object(phContext->dwLower, SCHAN_HANDLE_CTX))) return SEC_E_INVALID_HANDLE;
|
||||
if (!pInput) return is_dtls_context(ctx) ? SEC_E_INSUFFICIENT_MEMORY : SEC_E_INCOMPLETE_MESSAGE;
|
||||
if ((idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_TOKEN)) == -1) return SEC_E_INCOMPLETE_MESSAGE;
|
||||
if (!pInput && !is_dtls_context(ctx)) return SEC_E_INCOMPLETE_MESSAGE;
|
||||
|
||||
buffer = &pInput->pBuffers[idx];
|
||||
ptr = buffer->pvBuffer;
|
||||
expected_size = 0;
|
||||
|
||||
while (buffer->cbBuffer > expected_size + ctx->header_size)
|
||||
if (pInput)
|
||||
{
|
||||
record_size = ctx->header_size + read_record_size(ptr, ctx->header_size);
|
||||
if ((idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_TOKEN)) == -1) return SEC_E_INCOMPLETE_MESSAGE;
|
||||
|
||||
if (buffer->cbBuffer < expected_size + record_size) break;
|
||||
expected_size += record_size;
|
||||
ptr += record_size;
|
||||
buffer = &pInput->pBuffers[idx];
|
||||
ptr = buffer->pvBuffer;
|
||||
|
||||
while (buffer->cbBuffer > expected_size + ctx->header_size)
|
||||
{
|
||||
record_size = ctx->header_size + read_record_size(ptr, ctx->header_size);
|
||||
|
||||
if (buffer->cbBuffer < expected_size + record_size) break;
|
||||
expected_size += record_size;
|
||||
ptr += record_size;
|
||||
}
|
||||
|
||||
if (!expected_size)
|
||||
{
|
||||
TRACE("Expected at least %lu bytes, but buffer only contains %u bytes.\n",
|
||||
max(ctx->header_size + 1, record_size), buffer->cbBuffer);
|
||||
return SEC_E_INCOMPLETE_MESSAGE;
|
||||
}
|
||||
|
||||
TRACE("Using expected_size %lu.\n", expected_size);
|
||||
}
|
||||
|
||||
if (!expected_size)
|
||||
{
|
||||
TRACE("Expected at least %lu bytes, but buffer only contains %u bytes.\n",
|
||||
max(ctx->header_size + 1, record_size), buffer->cbBuffer);
|
||||
return SEC_E_INCOMPLETE_MESSAGE;
|
||||
}
|
||||
|
||||
TRACE("Using expected_size %lu.\n", expected_size);
|
||||
|
||||
if (phNewContext) *phNewContext = *phContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -1693,17 +1693,17 @@ static void test_dtls(void)
|
|||
ctx_handle2.dwLower = ctx_handle2.dwUpper = 0xdeadbeef;
|
||||
status = InitializeSecurityContextA( &cred_handle, &ctx_handle, (SEC_CHAR *)"winetest", flags_req, 0, 16, NULL, 0,
|
||||
&ctx_handle2, &buffers[1], &attr, &exp );
|
||||
todo_wine ok( status == SEC_I_CONTINUE_NEEDED, "got %08x\n", status );
|
||||
ok( status == SEC_I_CONTINUE_NEEDED, "got %08x\n", status );
|
||||
|
||||
flags_ret = ISC_RET_MANUAL_CRED_VALIDATION | ISC_RET_STREAM | ISC_RET_EXTENDED_ERROR | ISC_RET_DATAGRAM |
|
||||
ISC_RET_USED_SUPPLIED_CREDS | ISC_RET_CONFIDENTIALITY | ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT;
|
||||
todo_wine ok( attr == flags_ret, "got %08x\n", attr );
|
||||
ok( attr == flags_ret, "got %08x\n", attr );
|
||||
todo_wine ok( exp.LowPart, "got %08x\n", exp.LowPart );
|
||||
todo_wine ok( exp.HighPart, "got %08x\n", exp.HighPart );
|
||||
ok( buffers[1].pBuffers[1].BufferType == SECBUFFER_ALERT, "Expected buffertype SECBUFFER_ALERT, got %#x\n", buffers[1].pBuffers[1].BufferType);
|
||||
todo_wine ok( !buffers[1].pBuffers[1].cbBuffer, "Expected SECBUFFER_ALERT buffer to be empty, got %#x\n", buffers[1].pBuffers[1].cbBuffer);
|
||||
todo_wine ok( ctx_handle.dwLower == ctx_handle2.dwLower, "dwLower mismatch, expected %#lx, got %#lx\n", ctx_handle.dwLower, ctx_handle2.dwLower);
|
||||
todo_wine ok( ctx_handle.dwUpper == ctx_handle2.dwUpper, "dwUpper mismatch, expected %#lx, got %#lx\n", ctx_handle.dwUpper, ctx_handle2.dwUpper);
|
||||
ok( !buffers[1].pBuffers[1].cbBuffer, "Expected SECBUFFER_ALERT buffer to be empty, got %#x\n", buffers[1].pBuffers[1].cbBuffer);
|
||||
ok( ctx_handle.dwLower == ctx_handle2.dwLower, "dwLower mismatch, expected %#lx, got %#lx\n", ctx_handle.dwLower, ctx_handle2.dwLower);
|
||||
ok( ctx_handle.dwUpper == ctx_handle2.dwUpper, "dwUpper mismatch, expected %#lx, got %#lx\n", ctx_handle.dwUpper, ctx_handle2.dwUpper);
|
||||
|
||||
/* With no new input buffer, output buffer length should match prior call. */
|
||||
todo_wine ok(buffers[1].pBuffers[0].cbBuffer == prev_buf_len, "Output buffer size mismatch, expected %#x, got %#x\n",
|
||||
|
|
Loading…
Reference in New Issue