winhttp: Store the server certificate context in the request.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2018-06-11 09:20:35 +02:00 committed by Alexandre Julliard
parent 6bc984a600
commit f5ea51d360
5 changed files with 24 additions and 9 deletions

View File

@ -47,7 +47,6 @@
#include "windef.h"
#include "winbase.h"
#include "winhttp.h"
#include "wincrypt.h"
#include "schannel.h"
#include "winhttp_private.h"

View File

@ -1765,6 +1765,10 @@ static BOOL open_connection( request_t *request )
return FALSE;
}
}
CertFreeCertificateContext( request->server_cert );
request->server_cert = NULL;
if (!ensure_cred_handle( connect->session ) ||
!netconn_secure_connect( netconn, connect->hostname, request->security_flags,
&connect->session->cred_handle ))
@ -1787,6 +1791,13 @@ static BOOL open_connection( request_t *request )
request->netconn = netconn;
}
if (netconn->secure && !(request->server_cert = netconn_get_certificate( netconn )))
{
heap_free( addressW );
netconn_close( netconn );
return FALSE;
}
done:
request->read_pos = request->read_size = 0;
request->read_chunked = FALSE;

View File

@ -40,7 +40,6 @@
#include "winsock2.h"
#include "ws2ipdef.h"
#include "winhttp.h"
#include "wincrypt.h"
#include "winreg.h"
#define COBJMACROS
#include "ole2.h"
@ -597,6 +596,8 @@ static void request_destroy( object_header_t *hdr )
}
release_object( &request->connect->hdr );
CertFreeCertificateContext( request->server_cert );
destroy_authinfo( request->authinfo );
destroy_authinfo( request->proxy_authinfo );
@ -759,14 +760,14 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
return FALSE;
}
if (!request->netconn || !(cert = netconn_get_certificate( request->netconn ))) return FALSE;
if (!(cert = CertDuplicateCertificateContext( request->server_cert ))) return FALSE;
*(CERT_CONTEXT **)buffer = (CERT_CONTEXT *)cert;
*buflen = sizeof(cert);
return TRUE;
}
case WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT:
{
const CERT_CONTEXT *cert;
const CERT_CONTEXT *cert = request->server_cert;
const CRYPT_OID_INFO *oidInfo;
WINHTTP_CERTIFICATE_INFO *ci = buffer;
@ -778,16 +779,14 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
set_last_error( ERROR_INSUFFICIENT_BUFFER );
return FALSE;
}
if (!request->netconn || !(cert = netconn_get_certificate( request->netconn ))) return FALSE;
if (!cert) return FALSE;
ci->ftExpiry = cert->pCertInfo->NotAfter;
ci->ftStart = cert->pCertInfo->NotBefore;
ci->lpszSubjectInfo = blob_to_str( cert->dwCertEncodingType, &cert->pCertInfo->Subject );
ci->lpszIssuerInfo = blob_to_str( cert->dwCertEncodingType, &cert->pCertInfo->Issuer );
ci->lpszProtocolName = NULL;
oidInfo = CryptFindOIDInfo( CRYPT_OID_INFO_OID_KEY,
cert->pCertInfo->SignatureAlgorithm.pszObjId,
0 );
oidInfo = CryptFindOIDInfo( CRYPT_OID_INFO_OID_KEY, cert->pCertInfo->SignatureAlgorithm.pszObjId, 0 );
if (oidInfo)
ci->lpszSignatureAlgName = (LPWSTR)oidInfo->pwszName;
else
@ -795,7 +794,6 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
ci->lpszEncryptionAlgName = NULL;
ci->dwKeySize = request->netconn ? netconn_get_cipher_strength( request->netconn ) : 0;
CertFreeCertificateContext( cert );
*buflen = sizeof(*ci);
return TRUE;
}

View File

@ -1107,6 +1107,11 @@ static void test_secure_connection(void)
}
ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size);
size = sizeof(cert);
ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size);
ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
if (ret) CertFreeCertificateContext(cert);
cleanup:
WinHttpCloseHandle(req);
WinHttpCloseHandle(con);

View File

@ -46,6 +46,7 @@
#include "ole2.h"
#include "sspi.h"
#include "wincrypt.h"
static const WCHAR getW[] = {'G','E','T',0};
static const WCHAR postW[] = {'P','O','S','T',0};
@ -209,6 +210,7 @@ typedef struct
DWORD optional_len;
netconn_t *netconn;
DWORD security_flags;
const CERT_CONTEXT *server_cert;
int resolve_timeout;
int connect_timeout;
int send_timeout;