Hans Leidekker : winhttp: Implement WINHTTP_OPTION_CLIENT_CERT_CONTEXT.
Alexandre Julliard
julliard at winehq.org
Tue Jan 29 15:18:16 CST 2019
Module: wine
Branch: master
Commit: c68b5eb8500055c623486ad0b626a5f7691bfa89
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c68b5eb8500055c623486ad0b626a5f7691bfa89
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Jan 29 11:40:53 2019 +0100
winhttp: Implement WINHTTP_OPTION_CLIENT_CERT_CONTEXT.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winhttp/request.c | 23 +++++++++++++----------
dlls/winhttp/session.c | 32 +++++++++++++++++++++++++++++---
dlls/winhttp/winhttp_private.h | 5 +++--
3 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 5525c1c..af484cc 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -1527,25 +1527,28 @@ static DWORD map_secure_protocols( DWORD mask )
return ret;
}
-static BOOL ensure_cred_handle( struct session *session )
+static BOOL ensure_cred_handle( struct request *request )
{
SECURITY_STATUS status = SEC_E_OK;
- if (session->cred_handle_initialized) return TRUE;
+ if (request->cred_handle_initialized) return TRUE;
- EnterCriticalSection( &session->cs );
- if (!session->cred_handle_initialized)
+ if (!request->cred_handle_initialized)
{
SCHANNEL_CRED cred;
memset( &cred, 0, sizeof(cred) );
cred.dwVersion = SCHANNEL_CRED_VERSION;
- cred.grbitEnabledProtocols = map_secure_protocols( session->secure_protocols );
+ cred.grbitEnabledProtocols = map_secure_protocols( request->connect->session->secure_protocols );
+ if (request->client_cert)
+ {
+ cred.paCred = &request->client_cert;
+ cred.cCreds = 1;
+ }
status = AcquireCredentialsHandleW( NULL, (WCHAR *)UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL,
- &cred, NULL, NULL, &session->cred_handle, NULL );
+ &cred, NULL, NULL, &request->cred_handle, NULL );
if (status == SEC_E_OK)
- session->cred_handle_initialized = TRUE;
+ request->cred_handle_initialized = TRUE;
}
- LeaveCriticalSection( &session->cs );
if (status != SEC_E_OK)
{
@@ -1686,9 +1689,9 @@ static BOOL open_connection( struct request *request )
CertFreeCertificateContext( request->server_cert );
request->server_cert = NULL;
- if (!ensure_cred_handle( connect->session ) ||
+ if (!ensure_cred_handle( request ) ||
!netconn_secure_connect( netconn, connect->hostname, request->security_flags,
- &connect->session->cred_handle, request->check_revocation ))
+ &request->cred_handle, request->check_revocation ))
{
heap_free( addressW );
netconn_close( netconn );
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 82615ad..64fa8bb 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -81,7 +81,6 @@ static void session_destroy( struct object_header *hdr )
TRACE("%p\n", session);
if (session->unload_event) SetEvent( session->unload_event );
- if (session->cred_handle_initialized) FreeCredentialsHandle( &session->cred_handle );
destroy_cookies( session );
session->cs.DebugInfo->Spare[0] = 0;
@@ -610,7 +609,9 @@ static void request_destroy( struct object_header *hdr )
}
release_object( &request->connect->hdr );
+ if (request->cred_handle_initialized) FreeCredentialsHandle( &request->cred_handle );
CertFreeCertificateContext( request->server_cert );
+ CertFreeCertificateContext( request->client_cert );
destroy_authinfo( request->authinfo );
destroy_authinfo( request->proxy_authinfo );
@@ -1000,14 +1001,39 @@ static BOOL request_set_option( struct object_header *hdr, DWORD option, void *b
return TRUE;
}
case WINHTTP_OPTION_CLIENT_CERT_CONTEXT:
+ {
+ const CERT_CONTEXT *cert;
+
if (!(hdr->flags & WINHTTP_FLAG_SECURE))
{
SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE );
return FALSE;
}
- FIXME("WINHTTP_OPTION_CLIENT_CERT_CONTEXT\n");
- return TRUE;
+ if (!buffer)
+ {
+ CertFreeCertificateContext( request->client_cert );
+ request->client_cert = NULL;
+ }
+ else if (buflen >= sizeof(cert))
+ {
+ if (!(cert = CertDuplicateCertificateContext( buffer ))) return FALSE;
+ CertFreeCertificateContext( request->client_cert );
+ request->client_cert = cert;
+ }
+ else
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+ if (request->cred_handle_initialized)
+ {
+ FreeCredentialsHandle( &request->cred_handle );
+ request->cred_handle_initialized = FALSE;
+ }
+
+ return TRUE;
+ }
case WINHTTP_OPTION_ENABLE_FEATURE:
if(buflen == sizeof( DWORD ) && *(DWORD *)buffer == WINHTTP_ENABLE_SSL_REVOCATION)
{
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index b46f708..38e39cb 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -92,8 +92,6 @@ struct session
WCHAR *proxy_password;
struct list cookie_cache;
HANDLE unload_event;
- CredHandle cred_handle;
- BOOL cred_handle_initialized;
DWORD secure_protocols;
};
@@ -182,6 +180,9 @@ struct request
DWORD security_flags;
BOOL check_revocation;
const CERT_CONTEXT *server_cert;
+ const CERT_CONTEXT *client_cert;
+ CredHandle cred_handle;
+ BOOL cred_handle_initialized;
int resolve_timeout;
int connect_timeout;
int send_timeout;
More information about the wine-cvs
mailing list