Module: wine Branch: master Commit: abdae539381c03b874adda6bb8f85b3ec79eef22 URL: https://source.winehq.org/git/wine.git/?a=commit;h=abdae539381c03b874adda6bb...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Dec 3 15:48:28 2021 +0100
secur32: Move the memory allocation for get_unique_channel_binding() to the PE side.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/secur32/schannel.c | 21 ++++++++++++++++++++- dlls/secur32/schannel_gnutls.c | 21 ++++++--------------- dlls/secur32/secur32_priv.h | 2 +- 3 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c index 483e3285f09..432c35cdfde 100644 --- a/dlls/secur32/schannel.c +++ b/dlls/secur32/schannel.c @@ -1057,8 +1057,27 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW( } case SECPKG_ATTR_UNIQUE_BINDINGS: { + static const char prefix[] = "tls-unique:"; SecPkgContext_Bindings *bindings = buffer; - return schan_funcs->get_unique_channel_binding(ctx->transport.session, bindings); + ULONG size; + char *p; + + if (schan_funcs->get_unique_channel_binding(ctx->transport.session, NULL, &size) != SEC_E_BUFFER_TOO_SMALL) + return SEC_E_INTERNAL_ERROR; + + bindings->BindingsLength = sizeof(*bindings->Bindings) + sizeof(prefix)-1 + size; + /* freed with FreeContextBuffer */ + bindings->Bindings = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, bindings->BindingsLength); + if(!bindings->Bindings) + return SEC_E_INSUFFICIENT_MEMORY; + + bindings->Bindings->cbApplicationDataLength = sizeof(prefix)-1 + size; + bindings->Bindings->dwApplicationDataOffset = sizeof(*bindings->Bindings); + + p = (char*)(bindings->Bindings+1); + memcpy(p, prefix, sizeof(prefix)-1); + p += sizeof(prefix)-1; + return schan_funcs->get_unique_channel_binding(ctx->transport.session, p, &size); } case SECPKG_ATTR_APPLICATION_PROTOCOL: { diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c index 392d10e538b..e4da13c9b3e 100644 --- a/dlls/secur32/schannel_gnutls.c +++ b/dlls/secur32/schannel_gnutls.c @@ -755,13 +755,11 @@ static SECURITY_STATUS CDECL schan_get_connection_info(schan_session session, Se return SEC_E_OK; }
-static SECURITY_STATUS CDECL schan_get_unique_channel_binding(schan_session session, SecPkgContext_Bindings *bindings) +static SECURITY_STATUS CDECL schan_get_unique_channel_binding(schan_session session, void *buffer, ULONG *bufsize) { - static const char prefix[] = "tls-unique:"; gnutls_datum_t datum; int rc; SECURITY_STATUS ret; - char *p; gnutls_session_t s = (gnutls_session_t)session;
rc = pgnutls_session_channel_binding(s, GNUTLS_CB_TLS_UNIQUE, &datum); @@ -770,21 +768,14 @@ static SECURITY_STATUS CDECL schan_get_unique_channel_binding(schan_session sess pgnutls_perror(rc); return SEC_E_INTERNAL_ERROR; } - - bindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + sizeof(prefix)-1 + datum.size; - bindings->Bindings = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, bindings->BindingsLength); - if (!bindings->Bindings) - ret = SEC_E_INSUFFICIENT_MEMORY; - else + if (buffer && *bufsize >= datum.size) { - bindings->Bindings->cbApplicationDataLength = sizeof(prefix)-1 + datum.size; - bindings->Bindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS); - p = (char*)(bindings->Bindings+1); - memcpy(p, prefix, sizeof(prefix)-1); - p += sizeof(prefix)-1; - memcpy(p, datum.data, datum.size); + memcpy( buffer, datum.data, datum.size ); ret = SEC_E_OK; } + else ret = SEC_E_BUFFER_TOO_SMALL; + + *bufsize = datum.size; free(datum.data); return ret; } diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index 7cad59a51f7..9970c0847e3 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -121,7 +121,7 @@ struct schan_funcs unsigned int (CDECL *get_max_message_size)(schan_session); unsigned int (CDECL *get_session_cipher_block_size)(schan_session); SECURITY_STATUS (CDECL *get_session_peer_certificate)(schan_session, CERT_BLOB *, ULONG *, ULONG *); - SECURITY_STATUS (CDECL *get_unique_channel_binding)(schan_session, SecPkgContext_Bindings *); + SECURITY_STATUS (CDECL *get_unique_channel_binding)(schan_session, void *, ULONG *); SECURITY_STATUS (CDECL *handshake)(schan_session, SecBufferDesc *, SIZE_T, SecBufferDesc *, ULONG ); SECURITY_STATUS (CDECL *recv)(schan_session, SecBufferDesc *, SIZE_T, void *, SIZE_T *); SECURITY_STATUS (CDECL *send)(schan_session, SecBufferDesc *, const void *, SIZE_T *);