secur32: Better deal with the lack of gnutls_mac_get_key_size().

Francois Gouget fgouget at codeweavers.com
Wed Mar 25 06:07:56 CDT 2009


This improves compatibility with older GnuTLS libraries.
---

autoconf will need to be re-run.

The only reason why the compilation fails with older versions of GnuTLS 
(down to 2.0.2) is because we use typeof(gnutls_mac_get_key_size). But 
if we define the function pointer prototype ourselves, then compilation 
works just fine.

While I was at it I made a missing gnutls_mac_get_key_size function 
non-fatal and dealt with its absence in schan_QueryContextAttributesW(). 
Let me know if that does not make sense (maybe that function is 
systematically used?). If so, then dropping just that part of the patch 
would maintain the status quo, while allowing Wine compiled with an 
older library to keep working with the newer ones which is pretty 
pratical for Debian 4.0 and FreeBSD 7.0.


 configure.ac            |    2 +-
 dlls/secur32/schannel.c |   49 +++++++++++++++++++++++------------------------
 3 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/configure.ac b/configure.ac
index 3c2463c..a7f374d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -989,7 +989,7 @@ then
         CPPFLAGS="$CPPFLAGS $ac_gnutls_cflags"
     fi
     AC_CHECK_HEADER(gnutls/gnutls.h,
-        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], [[typeof(gnutls_mac_get_key_size) *pfunc;]])],
+        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <gnutls/gnutls.h>]], [[typeof(gnutls_transport_set_errno) *pfunc;]])],
             [WINE_CHECK_SONAME(gnutls,gnutls_global_init,
                 [AC_SUBST(GNUTLSINCL,"$ac_gnutls_cflags")],,[$ac_gnutls_libs])])])
     CPPFLAGS="$ac_save_CPPFLAGS"
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index fbf2a62..ea32d04 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -58,7 +58,8 @@ MAKE_FUNCPTR(gnutls_global_set_log_level);
 MAKE_FUNCPTR(gnutls_handshake);
 MAKE_FUNCPTR(gnutls_init);
 MAKE_FUNCPTR(gnutls_mac_get);
-MAKE_FUNCPTR(gnutls_mac_get_key_size);
+/* Don't use typeof() on this one for backward compatibility */
+static size_t (*pgnutls_mac_get_key_size)(gnutls_mac_algorithm_t);
 MAKE_FUNCPTR(gnutls_perror);
 MAKE_FUNCPTR(gnutls_set_default_priority);
 MAKE_FUNCPTR(gnutls_record_recv);
@@ -847,31 +848,27 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
     if (!context_handle) return SEC_E_INVALID_HANDLE;
     ctx = schan_get_object(context_handle->dwLower, SCHAN_HANDLE_CTX);
 
-    switch(attribute)
+    if (attribute == SECPKG_ATTR_STREAM_SIZES && pgnutls_mac_get_key_size)
     {
-        case SECPKG_ATTR_STREAM_SIZES:
-        {
-            SecPkgContext_StreamSizes *stream_sizes = buffer;
-            gnutls_mac_algorithm_t mac = pgnutls_mac_get(ctx->session);
-            size_t mac_size = pgnutls_mac_get_key_size(mac);
-            gnutls_cipher_algorithm_t cipher = pgnutls_cipher_get(ctx->session);
-            unsigned int block_size = schannel_get_cipher_block_size(cipher);
-
-            TRACE("Using %zu mac bytes, block size %u\n", mac_size, block_size);
-
-            /* These are defined by the TLS RFC */
-            stream_sizes->cbHeader = 5;
-            stream_sizes->cbTrailer = mac_size + 256; /* Max 255 bytes padding + 1 for padding size */
-            stream_sizes->cbMaximumMessage = 1 << 14;
-            stream_sizes->cbBuffers = 4;
-            stream_sizes->cbBlockSize = block_size;
-            return SEC_E_OK;
-        }
-
-        default:
-            FIXME("Unhandled attribute %#x\n", attribute);
-            return SEC_E_UNSUPPORTED_FUNCTION;
+        SecPkgContext_StreamSizes *stream_sizes = buffer;
+        gnutls_mac_algorithm_t mac = pgnutls_mac_get(ctx->session);
+        size_t mac_size = pgnutls_mac_get_key_size(mac);
+        gnutls_cipher_algorithm_t cipher = pgnutls_cipher_get(ctx->session);
+        unsigned int block_size = schannel_get_cipher_block_size(cipher);
+
+        TRACE("Using %zu mac bytes, block size %u\n", mac_size, block_size);
+
+        /* These are defined by the TLS RFC */
+        stream_sizes->cbHeader = 5;
+        stream_sizes->cbTrailer = mac_size + 256; /* Max 255 bytes padding + 1 for padding size */
+        stream_sizes->cbMaximumMessage = 1 << 14;
+        stream_sizes->cbBuffers = 4;
+        stream_sizes->cbBlockSize = block_size;
+        return SEC_E_OK;
     }
+
+    FIXME("Unhandled attribute %#x\n", attribute);
+    return SEC_E_UNSUPPORTED_FUNCTION;
 }
 
 static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesA(
@@ -1226,7 +1223,6 @@ void SECUR32_initSchannelSP(void)
     LOAD_FUNCPTR(gnutls_handshake)
     LOAD_FUNCPTR(gnutls_init)
     LOAD_FUNCPTR(gnutls_mac_get)
-    LOAD_FUNCPTR(gnutls_mac_get_key_size)
     LOAD_FUNCPTR(gnutls_perror)
     LOAD_FUNCPTR(gnutls_set_default_priority)
     LOAD_FUNCPTR(gnutls_record_recv);
@@ -1237,6 +1233,9 @@ void SECUR32_initSchannelSP(void)
     LOAD_FUNCPTR(gnutls_transport_set_push_function)
 #undef LOAD_FUNCPTR
 
+    /* Don't fail if this one is missing */
+    pgnutls_mac_get_key_size = wine_dlsym(libgnutls_handle, "gnutls_mac_get_key_size", NULL, 0);
+
     ret = pgnutls_global_init();
     if (ret != GNUTLS_E_SUCCESS)
     {
-- 
1.6.2




More information about the wine-patches mailing list