From 64a7d23565640b3815676cd53eba169fc246cccf Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Sun, 7 Sep 2008 21:30:31 +0200 Subject: [PATCH] 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(+) diff --git a/dlls/winhttp/Makefile.in b/dlls/winhttp/Makefile.in index e08355c2e5e..287ee4d9717 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 498e5ace095..e2c6cd62e2f 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 29510fcd48c..4e2289640bb 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 7cec99bb17a..05a9e549ca8 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 ) { -- 2.11.4.GIT