From: Paul Gofman <pgofman@codeweavers.com> --- dlls/winhttp/net.c | 9 ++++++--- dlls/winhttp/session.c | 22 ++++++---------------- dlls/winhttp/winhttp_private.h | 1 + 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index b0f405a9f52..05922acca00 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -81,7 +81,8 @@ static int sock_recv(int fd, void *msg, size_t len, int flags) return ret; } -static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation ) +static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation, + PCCERT_CHAIN_CONTEXT *ret_chain ) { HCERTSTORE store = cert->hCertStore; BOOL ret; @@ -92,6 +93,7 @@ static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD secu DWORD err = ERROR_SUCCESS; TRACE("verifying %s\n", debugstr_w( server )); + *ret_chain = NULL; chainPara.RequestedUsage.Usage.cUsageIdentifier = 1; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth; ret = CertGetCertificateChain( NULL, cert, NULL, store, &chainPara, @@ -169,7 +171,7 @@ static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD secu err = ERROR_WINHTTP_SECURE_INVALID_CERT; } } - CertFreeCertificateChain( chain ); + *ret_chain = chain; } else err = ERROR_WINHTTP_SECURE_CHANNEL_ERROR; @@ -296,6 +298,7 @@ void netconn_release( struct netconn *conn ) free(conn->ssl_read_buf); free(conn->ssl_write_buf); free(conn->extra_buf); + CertFreeCertificateChain(conn->chain); DeleteSecurityContext(&conn->ssl_ctx); } if (conn->socket != -1) @@ -400,7 +403,7 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur status = QueryContextAttributesW(&ctx, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert); if(status == SEC_E_OK) { - res = netconn_verify_cert(cert, hostname, security_flags, check_revocation); + res = netconn_verify_cert(cert, hostname, security_flags, check_revocation, &conn->chain); CertFreeCertificateContext(cert); if(res != ERROR_SUCCESS) { WARN( "cert verify failed: %lu\n", res ); diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index d06e208ac3d..f83c9a30c8c 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -912,28 +912,18 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void } case WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT: { - const CERT_CHAIN_CONTEXT *cert_chain; + const CERT_CHAIN_CONTEXT *chain; - char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH; - char *server_auth[] = { oid_server_auth }; - - CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; - - chainPara.RequestedUsage.Usage.cUsageIdentifier = 1; - chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth; - - if (!validate_buffer( buffer, buflen, sizeof(cert_chain) )) return FALSE; - if (!request || !request->server_cert) + if (!validate_buffer( buffer, buflen, sizeof(chain) )) return FALSE; + if (!request || !request->netconn || !request->netconn->chain) { SetLastError( ERROR_WINHTTP_INCORRECT_HANDLE_STATE ); *(CERT_CHAIN_CONTEXT **)buffer = NULL; return FALSE; } - if (!CertGetCertificateChain(NULL, request->server_cert, NULL, NULL, &chainPara, 0, NULL, &cert_chain)) return FALSE; - - *(CERT_CHAIN_CONTEXT **)buffer = (CERT_CHAIN_CONTEXT *)cert_chain; - *buflen = sizeof(cert_chain); - + if (!(chain = CertDuplicateCertificateChain( request->netconn->chain ))) return FALSE; + *(const CERT_CHAIN_CONTEXT **)buffer = chain; + *buflen = sizeof(chain); return TRUE; } case WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT: diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 99f57749856..46baccb1b93 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -110,6 +110,7 @@ struct netconn struct hostdata *host; ULONGLONG keep_until; CtxtHandle ssl_ctx; + PCCERT_CHAIN_CONTEXT chain; SecPkgContext_StreamSizes ssl_sizes; char *ssl_read_buf, *ssl_write_buf; char *extra_buf; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11546