Alexandre Julliard : secur32: Move the memory allocation for get_unique_channel_binding() to the PE side.

Alexandre Julliard julliard at winehq.org
Mon Dec 6 16:07:58 CST 2021


Module: wine
Branch: master
Commit: abdae539381c03b874adda6bb8f85b3ec79eef22
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=abdae539381c03b874adda6bb8f85b3ec79eef22

Author: Alexandre Julliard <julliard at 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 at 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 *);




More information about the wine-cvs mailing list