Hans Leidekker : winhttp: Implement WINHTTP_OPTION_SERVER_CERT_CONTEXT.
Alexandre Julliard
julliard at winehq.org
Mon Sep 8 07:41:32 CDT 2008
Module: wine
Branch: master
Commit: 64a7d23565640b3815676cd53eba169fc246cccf
URL: http://source.winehq.org/git/wine.git/?a=commit;h=64a7d23565640b3815676cd53eba169fc246cccf
Author: Hans Leidekker <hans at codeweavers.com>
Date: Sun Sep 7 21:30:31 2008 +0200
winhttp: Implement WINHTTP_OPTION_SERVER_CERT_CONTEXT.
---
dlls/winhttp/Makefile.in | 1 +
dlls/winhttp/net.c | 46 ++++++++++++++++++++++++++++++++++++++++
dlls/winhttp/session.c | 17 ++++++++++++++
dlls/winhttp/winhttp_private.h | 1 +
4 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in
index e08355c..287ee4d 100644
--- a/dlls/winhttp/Makefile.in
+++ b/dlls/winhttp/Makefile.in
@@ -5,6 +5,7 @@ VPATH = @srcdir@
MODULE = winhttp.dll
IMPORTLIB = winhttp
IMPORTS = wininet kernel32
+DELAYIMPORTS = crypt32
C_SRCS = \
handle.c \
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 498e5ac..e2c6cd6 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -48,6 +48,7 @@
#include "windef.h"
#include "winbase.h"
#include "winhttp.h"
+#include "wincrypt.h"
/* to avoid conflicts with the Unix socket headers */
#define USE_WS_PREFIX
@@ -102,6 +103,7 @@ MAKE_FUNCPTR( SSL_get_peer_certificate );
MAKE_FUNCPTR( SSL_CTX_get_timeout );
MAKE_FUNCPTR( SSL_CTX_set_timeout );
MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths );
+MAKE_FUNCPTR( i2d_X509 );
MAKE_FUNCPTR( BIO_new_fp );
MAKE_FUNCPTR( ERR_get_error );
@@ -218,6 +220,7 @@ BOOL netconn_init( netconn_t *conn, BOOL secure )
LOAD_FUNCPTR( SSL_CTX_get_timeout );
LOAD_FUNCPTR( SSL_CTX_set_timeout );
LOAD_FUNCPTR( SSL_CTX_set_default_verify_paths );
+ LOAD_FUNCPTR( i2d_X509 );
#undef LOAD_FUNCPTR
#define LOAD_FUNCPTR(x) \
@@ -616,3 +619,46 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr_in *
#endif
return TRUE;
}
+
+const void *netconn_get_certificate( netconn_t *conn )
+{
+#ifdef SONAME_LIBSSL
+ X509 *cert;
+ unsigned char *buffer, *p;
+ int len;
+ BOOL malloc = FALSE;
+ const CERT_CONTEXT *ret;
+
+ if (!conn->secure) return NULL;
+
+ if (!(cert = pSSL_get_peer_certificate( conn->ssl_conn ))) return NULL;
+ p = NULL;
+ if ((len = pi2d_X509( cert, &p )) < 0) return NULL;
+ /*
+ * SSL 0.9.7 and above malloc the buffer if it is null.
+ * however earlier version do not and so we would need to alloc the buffer.
+ *
+ * see the i2d_X509 man page for more details.
+ */
+ if (!p)
+ {
+ if (!(buffer = heap_alloc( len ))) return NULL;
+ p = buffer;
+ len = pi2d_X509( cert, &p );
+ }
+ else
+ {
+ buffer = p;
+ malloc = TRUE;
+ }
+
+ ret = CertCreateCertificateContext( X509_ASN_ENCODING, buffer, len );
+
+ if (malloc) free( buffer );
+ else heap_free( buffer );
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 29510fc..4e22896 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -25,6 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "winhttp.h"
+#include "wincrypt.h"
#include "winhttp_private.h"
@@ -264,6 +265,22 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
*buflen = sizeof(DWORD);
return TRUE;
}
+ case WINHTTP_OPTION_SERVER_CERT_CONTEXT:
+ {
+ const CERT_CONTEXT *cert;
+ request_t *request = (request_t *)hdr;
+
+ if (!(cert = netconn_get_certificate( &request->netconn ))) return FALSE;
+ memcpy( buffer, cert, sizeof(CERT_CONTEXT) );
+ *buflen = sizeof(cert);
+ return TRUE;
+ }
+ case WINHTTP_OPTION_SECURITY_KEY_BITNESS:
+ {
+ *(DWORD *)buffer = 128; /* FIXME */
+ *buflen = sizeof(DWORD);
+ return TRUE;
+ }
default:
FIXME("unimplemented option %u\n", option);
return FALSE;
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 7cec99b..05a9e54 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -143,6 +143,7 @@ BOOL netconn_recv( netconn_t *, void *, size_t, int, int * );
BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_in * );
BOOL netconn_secure_connect( netconn_t * );
BOOL netconn_send( netconn_t *, const void *, size_t, int, int * );
+const void *netconn_get_certificate( netconn_t * );
static inline void *heap_alloc( SIZE_T size )
{
More information about the wine-cvs
mailing list