mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 02:39:46 +00:00
secur32: Manage gnutls transport data in unixlib.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
3f2cdb6820
commit
c1d9d6e06e
|
@ -61,7 +61,7 @@ struct schan_handle
|
|||
|
||||
struct schan_context
|
||||
{
|
||||
struct schan_transport transport;
|
||||
schan_session session;
|
||||
ULONG req_ctx_attr;
|
||||
const CERT_CONTEXT *cert;
|
||||
SIZE_T header_size;
|
||||
|
@ -758,14 +758,15 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
{
|
||||
const ULONG extra_size = 0x10000;
|
||||
struct schan_context *ctx;
|
||||
struct schan_buffers *out_buffers;
|
||||
struct schan_credentials *cred;
|
||||
SIZE_T expected_size = 0;
|
||||
SECURITY_STATUS ret;
|
||||
SecBuffer *buffer;
|
||||
SecBuffer alloc_buffer = { 0 };
|
||||
struct handshake_params params;
|
||||
struct handshake_params params = { 0 };
|
||||
int output_buffer_idx = -1;
|
||||
int idx, i;
|
||||
ULONG input_offset = 0, output_offset = 0;
|
||||
|
||||
TRACE("%p %p %s 0x%08lx %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
|
||||
debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
|
||||
|
@ -815,9 +816,8 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
return SEC_E_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
create_params.transport = &ctx->transport;
|
||||
create_params.cred = cred;
|
||||
create_params.session = &ctx->transport.session;
|
||||
create_params.session = &ctx->session;
|
||||
if (GNUTLS_CALL( create_session, &create_params ))
|
||||
{
|
||||
schan_free_handle(handle, SCHAN_HANDLE_CTX);
|
||||
|
@ -837,7 +837,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
|
||||
if (target)
|
||||
{
|
||||
struct set_session_target_params params = { ctx->transport.session, target };
|
||||
struct set_session_target_params params = { ctx->session, target };
|
||||
WideCharToMultiByte( CP_UNIXCP, 0, pszTargetName, -1, target, len, NULL, NULL );
|
||||
GNUTLS_CALL( set_session_target, ¶ms );
|
||||
free( target );
|
||||
|
@ -846,8 +846,8 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
|
||||
if (pInput && (idx = schan_find_sec_buffer_idx(pInput, 0, SECBUFFER_APPLICATION_PROTOCOLS)) != -1)
|
||||
{
|
||||
struct set_application_protocols_params params = { ctx->transport.session,
|
||||
pInput->pBuffers[idx].pvBuffer, pInput->pBuffers[idx].cbBuffer };
|
||||
struct set_application_protocols_params params = { ctx->session, pInput->pBuffers[idx].pvBuffer,
|
||||
pInput->pBuffers[idx].cbBuffer };
|
||||
GNUTLS_CALL( set_application_protocols, ¶ms );
|
||||
}
|
||||
|
||||
|
@ -856,7 +856,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
buffer = &pInput->pBuffers[idx];
|
||||
if (buffer->cbBuffer >= sizeof(WORD))
|
||||
{
|
||||
struct set_dtls_mtu_params params = { ctx->transport.session, *(WORD *)buffer->pvBuffer };
|
||||
struct set_dtls_mtu_params params = { ctx->session, *(WORD *)buffer->pvBuffer };
|
||||
GNUTLS_CALL( set_dtls_mtu, ¶ms );
|
||||
}
|
||||
else WARN("invalid buffer size %lu\n", buffer->cbBuffer);
|
||||
|
@ -864,7 +864,7 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
|
||||
if (is_dtls_context(ctx))
|
||||
{
|
||||
struct set_dtls_timeouts_params params = { ctx->transport.session, 0, 60000 };
|
||||
struct set_dtls_timeouts_params params = { ctx->session, 0, 60000 };
|
||||
GNUTLS_CALL( set_dtls_timeouts, ¶ms );
|
||||
}
|
||||
|
||||
|
@ -917,18 +917,20 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
alloc_buffer.BufferType = SECBUFFER_TOKEN;
|
||||
alloc_buffer.pvBuffer = RtlAllocateHeap( GetProcessHeap(), 0, extra_size );
|
||||
}
|
||||
params.session = ctx->transport.session;
|
||||
params.session = ctx->session;
|
||||
params.input = pInput;
|
||||
params.input_size = expected_size;
|
||||
params.output = pOutput;
|
||||
params.alloc_buffer = &alloc_buffer;
|
||||
params.input_offset = &input_offset;
|
||||
params.output_buffer_idx = &output_buffer_idx;
|
||||
params.output_offset = &output_offset;
|
||||
ret = GNUTLS_CALL( handshake, ¶ms );
|
||||
|
||||
out_buffers = &ctx->transport.out;
|
||||
if (out_buffers->current_buffer_idx != -1)
|
||||
if (output_buffer_idx != -1)
|
||||
{
|
||||
SecBuffer *buffer = &out_buffers->desc->pBuffers[out_buffers->current_buffer_idx];
|
||||
buffer->cbBuffer = out_buffers->offset;
|
||||
SecBuffer *buffer = &pOutput->pBuffers[output_buffer_idx];
|
||||
buffer->cbBuffer = output_offset;
|
||||
if (buffer->pvBuffer == alloc_buffer.pvBuffer)
|
||||
{
|
||||
RtlReAllocateHeap( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY,
|
||||
|
@ -936,19 +938,19 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
|
|||
alloc_buffer.pvBuffer = NULL;
|
||||
}
|
||||
}
|
||||
else if (out_buffers->desc && out_buffers->desc->cBuffers > 0)
|
||||
else if (pOutput && pOutput->cBuffers)
|
||||
{
|
||||
SecBuffer *buffer = &out_buffers->desc->pBuffers[0];
|
||||
buffer->cbBuffer = 0;
|
||||
pOutput->pBuffers[0].cbBuffer = 0;
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, alloc_buffer.pvBuffer );
|
||||
|
||||
if(ctx->transport.in.offset && ctx->transport.in.offset != pInput->pBuffers[0].cbBuffer) {
|
||||
if (input_offset && input_offset != pInput->pBuffers[0].cbBuffer)
|
||||
{
|
||||
if(pInput->cBuffers<2 || pInput->pBuffers[1].BufferType!=SECBUFFER_EMPTY)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
pInput->pBuffers[1].BufferType = SECBUFFER_EXTRA;
|
||||
pInput->pBuffers[1].cbBuffer = pInput->pBuffers[0].cbBuffer-ctx->transport.in.offset;
|
||||
pInput->pBuffers[1].cbBuffer = pInput->pBuffers[0].cbBuffer - input_offset;
|
||||
}
|
||||
|
||||
for (i = 0; i < pOutput->cBuffers; i++)
|
||||
|
@ -1031,7 +1033,7 @@ static SECURITY_STATUS ensure_remote_cert(struct schan_context *ctx)
|
|||
PCCERT_CONTEXT cert = NULL;
|
||||
SECURITY_STATUS status;
|
||||
ULONG count, size = 0;
|
||||
struct get_session_peer_certificate_params params = { ctx->transport.session, NULL, &size, &count };
|
||||
struct get_session_peer_certificate_params params = { ctx->session, NULL, &size, &count };
|
||||
|
||||
if (ctx->cert) return SEC_E_OK;
|
||||
if (!(store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL)))
|
||||
|
@ -1089,11 +1091,11 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
|
|||
case SECPKG_ATTR_STREAM_SIZES:
|
||||
{
|
||||
SecPkgContext_ConnectionInfo info;
|
||||
struct get_connection_info_params params = { ctx->transport.session, &info };
|
||||
struct get_connection_info_params params = { ctx->session, &info };
|
||||
status = GNUTLS_CALL( get_connection_info, ¶ms );
|
||||
if (status == SEC_E_OK)
|
||||
{
|
||||
struct session_params params = { ctx->transport.session };
|
||||
struct session_params params = { ctx->session };
|
||||
SecPkgContext_StreamSizes *stream_sizes = buffer;
|
||||
SIZE_T mac_size = info.dwHashStrength;
|
||||
unsigned int block_size = GNUTLS_CALL( get_session_cipher_block_size, ¶ms );
|
||||
|
@ -1115,11 +1117,11 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
|
|||
case SECPKG_ATTR_KEY_INFO:
|
||||
{
|
||||
SecPkgContext_ConnectionInfo conn_info;
|
||||
struct get_connection_info_params params = { ctx->transport.session, &conn_info };
|
||||
struct get_connection_info_params params = { ctx->session, &conn_info };
|
||||
status = GNUTLS_CALL( get_connection_info, ¶ms );
|
||||
if (status == SEC_E_OK)
|
||||
{
|
||||
struct session_params params = { ctx->transport.session };
|
||||
struct session_params params = { ctx->session };
|
||||
SecPkgContext_KeyInfoW *info = buffer;
|
||||
info->KeySize = conn_info.dwCipherStrength;
|
||||
info->SignatureAlgorithm = GNUTLS_CALL( get_key_signature_algorithm, ¶ms );
|
||||
|
@ -1143,7 +1145,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
|
|||
case SECPKG_ATTR_CONNECTION_INFO:
|
||||
{
|
||||
SecPkgContext_ConnectionInfo *info = buffer;
|
||||
struct get_connection_info_params params = { ctx->transport.session, info };
|
||||
struct get_connection_info_params params = { ctx->session, info };
|
||||
return GNUTLS_CALL( get_connection_info, ¶ms );
|
||||
}
|
||||
case SECPKG_ATTR_ENDPOINT_BINDINGS:
|
||||
|
@ -1193,7 +1195,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
|
|||
SecPkgContext_Bindings *bindings = buffer;
|
||||
ULONG size;
|
||||
char *p;
|
||||
struct get_unique_channel_binding_params params = { ctx->transport.session, NULL, &size };
|
||||
struct get_unique_channel_binding_params params = { ctx->session, NULL, &size };
|
||||
|
||||
if (GNUTLS_CALL( get_unique_channel_binding, ¶ms ) != SEC_E_BUFFER_TOO_SMALL)
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
@ -1216,7 +1218,7 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
|
|||
case SECPKG_ATTR_APPLICATION_PROTOCOL:
|
||||
{
|
||||
SecPkgContext_ApplicationProtocol *protocol = buffer;
|
||||
struct get_application_protocol_params params = { ctx->transport.session, protocol };
|
||||
struct get_application_protocol_params params = { ctx->session, protocol };
|
||||
return GNUTLS_CALL( get_application_protocol, ¶ms );
|
||||
}
|
||||
|
||||
|
@ -1297,7 +1299,7 @@ static SECURITY_STATUS SEC_ENTRY schan_EncryptMessage(PCtxtHandle context_handle
|
|||
memcpy(data, buffer->pvBuffer, data_size);
|
||||
|
||||
length = data_size;
|
||||
params.session = ctx->transport.session;
|
||||
params.session = ctx->session;
|
||||
params.output = message;
|
||||
params.buffer = data;
|
||||
params.length = &length;
|
||||
|
@ -1421,7 +1423,7 @@ static SECURITY_STATUS SEC_ENTRY schan_DecryptMessage(PCtxtHandle context_handle
|
|||
|
||||
received = data_size;
|
||||
|
||||
params.session = ctx->transport.session;
|
||||
params.session = ctx->session;
|
||||
params.input = message;
|
||||
params.input_size = expected_size;
|
||||
params.buffer = data;
|
||||
|
@ -1469,7 +1471,7 @@ static SECURITY_STATUS SEC_ENTRY schan_DeleteSecurityContext(PCtxtHandle context
|
|||
if (!ctx) return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (ctx->cert) CertFreeCertificateContext(ctx->cert);
|
||||
params.session = ctx->transport.session;
|
||||
params.session = ctx->session;
|
||||
GNUTLS_CALL( dispose_session, ¶ms );
|
||||
free(ctx);
|
||||
return SEC_E_OK;
|
||||
|
@ -1610,7 +1612,7 @@ void SECUR32_deinitSchannelSP(void)
|
|||
if (schan_handle_table[i].type == SCHAN_HANDLE_CTX)
|
||||
{
|
||||
struct schan_context *ctx = schan_free_handle(i, SCHAN_HANDLE_CTX);
|
||||
struct session_params params = { ctx->transport.session };
|
||||
struct session_params params = { ctx->session };
|
||||
GNUTLS_CALL( dispose_session, ¶ms );
|
||||
free(ctx);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,23 @@ static inline gnutls_session_t session_from_handle(UINT64 handle)
|
|||
return (gnutls_session_t)(ULONG_PTR)handle;
|
||||
}
|
||||
|
||||
struct schan_buffers
|
||||
{
|
||||
SIZE_T offset;
|
||||
SIZE_T limit;
|
||||
const SecBufferDesc *desc;
|
||||
SecBuffer *alloc_buffer;
|
||||
int current_buffer_idx;
|
||||
int (*get_next_buffer)(struct schan_buffers *);
|
||||
};
|
||||
|
||||
struct schan_transport
|
||||
{
|
||||
gnutls_session_t session;
|
||||
struct schan_buffers in;
|
||||
struct schan_buffers out;
|
||||
};
|
||||
|
||||
static int compat_cipher_get_block_size(gnutls_cipher_algorithm_t cipher)
|
||||
{
|
||||
switch(cipher) {
|
||||
|
@ -374,7 +391,6 @@ static char *get_buffer(struct schan_buffers *s, SIZE_T *count)
|
|||
static ssize_t pull_adapter(gnutls_transport_ptr_t transport, void *buff, size_t buff_len)
|
||||
{
|
||||
struct schan_transport *t = (struct schan_transport*)transport;
|
||||
gnutls_session_t s = session_from_handle(t->session);
|
||||
SIZE_T len = buff_len;
|
||||
char *b;
|
||||
|
||||
|
@ -383,7 +399,7 @@ static ssize_t pull_adapter(gnutls_transport_ptr_t transport, void *buff, size_t
|
|||
b = get_buffer(&t->in, &len);
|
||||
if (!b)
|
||||
{
|
||||
pgnutls_transport_set_errno(s, EAGAIN);
|
||||
pgnutls_transport_set_errno(t->session, EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
memcpy(buff, b, len);
|
||||
|
@ -395,7 +411,6 @@ static ssize_t pull_adapter(gnutls_transport_ptr_t transport, void *buff, size_t
|
|||
static ssize_t push_adapter(gnutls_transport_ptr_t transport, const void *buff, size_t buff_len)
|
||||
{
|
||||
struct schan_transport *t = (struct schan_transport*)transport;
|
||||
gnutls_session_t s = session_from_handle(t->session);
|
||||
SIZE_T len = buff_len;
|
||||
char *b;
|
||||
|
||||
|
@ -404,7 +419,7 @@ static ssize_t push_adapter(gnutls_transport_ptr_t transport, const void *buff,
|
|||
b = get_buffer(&t->out, &len);
|
||||
if (!b)
|
||||
{
|
||||
pgnutls_transport_set_errno(s, EAGAIN);
|
||||
pgnutls_transport_set_errno(t->session, EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
memcpy(b, buff, len);
|
||||
|
@ -483,6 +498,7 @@ static NTSTATUS schan_create_session( void *args )
|
|||
char priority[128] = "NORMAL:%LATEST_RECORD_VERSION", *p;
|
||||
BOOL using_vers_all = FALSE, disabled;
|
||||
unsigned int i, flags = (cred->credential_use == SECPKG_CRED_INBOUND) ? GNUTLS_SERVER : GNUTLS_CLIENT;
|
||||
struct schan_transport *transport;
|
||||
gnutls_session_t s;
|
||||
int err;
|
||||
|
||||
|
@ -500,6 +516,13 @@ static NTSTATUS schan_create_session( void *args )
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (!(transport = calloc(1, sizeof(*transport))))
|
||||
{
|
||||
pgnutls_deinit(s);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
transport->session = s;
|
||||
|
||||
p = priority + strlen(priority);
|
||||
|
||||
/* VERS-ALL is nice to use for forward compatibility. It was introduced before support for TLS1.3,
|
||||
|
@ -531,6 +554,7 @@ static NTSTATUS schan_create_session( void *args )
|
|||
{
|
||||
pgnutls_perror(err);
|
||||
pgnutls_deinit(s);
|
||||
free(transport);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
|
@ -540,13 +564,14 @@ static NTSTATUS schan_create_session( void *args )
|
|||
{
|
||||
pgnutls_perror(err);
|
||||
pgnutls_deinit(s);
|
||||
free(transport);
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
pgnutls_transport_set_pull_function(s, pull_adapter);
|
||||
if (flags & GNUTLS_DATAGRAM) pgnutls_transport_set_pull_timeout_function(s, pull_timeout);
|
||||
pgnutls_transport_set_push_function(s, push_adapter);
|
||||
pgnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)params->transport);
|
||||
pgnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)transport);
|
||||
*params->session = (ULONG_PTR)s;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -556,7 +581,10 @@ static NTSTATUS schan_dispose_session( void *args )
|
|||
{
|
||||
const struct session_params *params = args;
|
||||
gnutls_session_t s = session_from_handle(params->session);
|
||||
struct schan_transport *t = (struct schan_transport *)pgnutls_transport_get_ptr(s);
|
||||
pgnutls_transport_set_ptr(s, NULL);
|
||||
pgnutls_deinit(s);
|
||||
free(t);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -573,6 +601,7 @@ static NTSTATUS schan_handshake( void *args )
|
|||
const struct handshake_params *params = args;
|
||||
gnutls_session_t s = session_from_handle(params->session);
|
||||
struct schan_transport *t = (struct schan_transport *)pgnutls_transport_get_ptr(s);
|
||||
NTSTATUS status;
|
||||
int err;
|
||||
|
||||
init_schan_buffers(&t->in, params->input, handshake_get_next_buffer);
|
||||
|
@ -580,47 +609,52 @@ static NTSTATUS schan_handshake( void *args )
|
|||
init_schan_buffers(&t->out, params->output, handshake_get_next_buffer_alloc );
|
||||
t->out.alloc_buffer = params->alloc_buffer;
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
err = pgnutls_handshake(s);
|
||||
switch(err) {
|
||||
case GNUTLS_E_SUCCESS:
|
||||
if (err == GNUTLS_E_SUCCESS)
|
||||
{
|
||||
TRACE("Handshake completed\n");
|
||||
return SEC_E_OK;
|
||||
|
||||
case GNUTLS_E_AGAIN:
|
||||
status = SEC_E_OK;
|
||||
}
|
||||
else if (err == GNUTLS_E_AGAIN)
|
||||
{
|
||||
TRACE("Continue...\n");
|
||||
return SEC_I_CONTINUE_NEEDED;
|
||||
|
||||
case GNUTLS_E_WARNING_ALERT_RECEIVED:
|
||||
status = SEC_I_CONTINUE_NEEDED;
|
||||
}
|
||||
else if (err == GNUTLS_E_WARNING_ALERT_RECEIVED)
|
||||
{
|
||||
gnutls_alert_description_t alert = pgnutls_alert_get(s);
|
||||
|
||||
WARN("WARNING ALERT: %d %s\n", alert, pgnutls_alert_get_name(alert));
|
||||
|
||||
switch(alert) {
|
||||
case GNUTLS_A_UNRECOGNIZED_NAME:
|
||||
if (alert == GNUTLS_A_UNRECOGNIZED_NAME)
|
||||
{
|
||||
TRACE("Ignoring\n");
|
||||
continue;
|
||||
default:
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
}
|
||||
else
|
||||
status = SEC_E_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
case GNUTLS_E_FATAL_ALERT_RECEIVED:
|
||||
else if (err == GNUTLS_E_FATAL_ALERT_RECEIVED)
|
||||
{
|
||||
gnutls_alert_description_t alert = pgnutls_alert_get(s);
|
||||
WARN("FATAL ALERT: %d %s\n", alert, pgnutls_alert_get_name(alert));
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
status = SEC_E_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
default:
|
||||
else
|
||||
{
|
||||
pgnutls_perror(err);
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
status = SEC_E_INTERNAL_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Never reached */
|
||||
return SEC_E_OK;
|
||||
*params->input_offset = t->in.offset;
|
||||
*params->output_buffer_idx = t->out.current_buffer_idx;
|
||||
*params->output_offset = t->out.offset;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static DWORD get_protocol(gnutls_protocol_t proto)
|
||||
|
|
|
@ -88,23 +88,6 @@ typedef struct schan_credentials
|
|||
DWORD enabled_protocols;
|
||||
} schan_credentials;
|
||||
|
||||
struct schan_buffers
|
||||
{
|
||||
SIZE_T offset;
|
||||
SIZE_T limit;
|
||||
const SecBufferDesc *desc;
|
||||
SecBuffer *alloc_buffer;
|
||||
int current_buffer_idx;
|
||||
int (*get_next_buffer)(struct schan_buffers *);
|
||||
};
|
||||
|
||||
struct schan_transport
|
||||
{
|
||||
schan_session session;
|
||||
struct schan_buffers in;
|
||||
struct schan_buffers out;
|
||||
};
|
||||
|
||||
struct session_params
|
||||
{
|
||||
schan_session session;
|
||||
|
@ -122,7 +105,6 @@ struct allocate_certificate_credentials_params
|
|||
|
||||
struct create_session_params
|
||||
{
|
||||
struct schan_transport *transport;
|
||||
schan_credentials *cred;
|
||||
schan_session *session;
|
||||
};
|
||||
|
@ -166,6 +148,9 @@ struct handshake_params
|
|||
SIZE_T input_size;
|
||||
SecBufferDesc *output;
|
||||
SecBuffer *alloc_buffer;
|
||||
ULONG *input_offset;
|
||||
int *output_buffer_idx;
|
||||
ULONG *output_offset;
|
||||
};
|
||||
|
||||
struct recv_params
|
||||
|
|
Loading…
Reference in a new issue