From: Paul Gofman <pgofman@codeweavers.com> --- dlls/winhttp/session.c | 6 ++++++ dlls/winhttp/tests/winhttp.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 85e3c3f18d1..eb02c5f00bb 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -923,6 +923,12 @@ static BOOL request_query_option( struct object_header *hdr, DWORD option, void chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth; if (!validate_buffer( buffer, buflen, sizeof(cert_chain) )) return FALSE; + if (!request->server_cert) + { + 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; diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index f639877d2ab..4caf2abee38 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -1099,6 +1099,9 @@ static void test_secure_connection(void) CERT_CONTEXT *cert; WINHTTP_CERTIFICATE_INFO info; WINHTTP_SECURITY_INFO secinfo; + PCCERT_CHAIN_CONTEXT chain; + CERT_CHAIN_POLICY_PARA chain_policy = { .cbSize = sizeof(chain_policy) }; + CERT_CHAIN_POLICY_STATUS policy_status = { .cbSize = sizeof(policy_status) }; char buffer[32]; ses = WinHttpOpen(L"winetest", 0, NULL, NULL, 0); @@ -1152,9 +1155,25 @@ static void test_secure_connection(void) WinHttpCloseHandle(req); + size = sizeof(chain); + chain = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT, &chain, &size); + ok(!ret, "unexpected success.\n"); + todo_wine ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, "got error %lu.\n", GetLastError()); + ok(chain == (void *)0xdeadbeef, "got %p.\n", chain); + req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE); ok(req != NULL, "failed to open a request %lu\n", GetLastError()); + size = sizeof(chain); + chain = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT, &chain, &size); + ok(!ret, "unexpected success.\n"); + ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got error %lu.\n", GetLastError()); + ok(!chain, "got %p.\n", chain); + flags = 0xdeadbeef; size = sizeof(flags); ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_FLAGS, &flags, &size); @@ -1198,6 +1217,18 @@ static void test_secure_connection(void) } ok(ret, "failed to send request %lu\n", GetLastError()); + size = sizeof(chain); + chain = (void *)0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT, &chain, &size); + ok(ret, "got error %lu.\n", GetLastError()); + ok(chain && chain != (void *)0xdeadbeef, "got %p.\n", chain); + ret = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chain, &chain_policy, &policy_status); + ok(ret, "got error %lu.\n", GetLastError()); + ok(!chain->TrustStatus.dwErrorStatus, "got %#lx.\n", chain->TrustStatus.dwErrorStatus); + ok(!policy_status.dwError, "got %#lx.\n", policy_status.dwError); + CertFreeCertificateChain(chain); + size = sizeof(cert); ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size ); ok(ret, "failed to retrieve certificate context %lu\n", GetLastError()); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11546