This also fixes a regression caused by 0b61334b9d6392e8c8a9772d762efaf0c2eb0835, which is causing Office 2013 to fail to login, saying that there is a problem with your account.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/winhttp/net.c | 14 ++++++++------ dlls/winhttp/request.c | 2 +- dlls/winhttp/session.c | 12 ++++++++++++ dlls/winhttp/tests/winhttp.c | 31 +++++++++++++++++++++++++++++++ dlls/winhttp/winhttp_private.h | 3 ++- 5 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index d577a64783..2625e4a9d7 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -160,7 +160,7 @@ 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 ) +static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD security_flags, BOOL check_revocation ) { HCERTSTORE store = cert->hCertStore; BOOL ret; @@ -173,9 +173,10 @@ static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD secu TRACE("verifying %s\n", debugstr_w( server )); chainPara.RequestedUsage.Usage.cUsageIdentifier = 1; chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth; - if ((ret = CertGetCertificateChain( NULL, cert, NULL, store, &chainPara, - CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, - NULL, &chain ))) + ret = CertGetCertificateChain( NULL, cert, NULL, store, &chainPara, + check_revocation ? CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT : 0, + NULL, &chain ); + if (ret) { if (chain->TrustStatus.dwErrorStatus) { @@ -370,7 +371,8 @@ BOOL netconn_close( netconn_t *conn ) return TRUE; }
-BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle ) +BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, + BOOL check_revocation) { SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}}; SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs}; @@ -466,7 +468,7 @@ BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_fl
status = QueryContextAttributesW(&ctx, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&cert); if(status == SEC_E_OK) { - res = netconn_verify_cert(cert, hostname, security_flags); + res = netconn_verify_cert(cert, hostname, security_flags, check_revocation); CertFreeCertificateContext(cert); if(res != ERROR_SUCCESS) { WARN("cert verify failed: %u\n", res); diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 5e5b229a1f..65d641f3cb 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1769,7 +1769,7 @@ static BOOL open_connection( request_t *request )
if (!ensure_cred_handle( connect->session ) || !netconn_secure_connect( netconn, connect->hostname, request->security_flags, - &connect->session->cred_handle )) + &connect->session->cred_handle, request->check_revocation )) { heap_free( addressW ); netconn_close( netconn ); diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index fb815682c2..788f7c613f 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -1020,6 +1020,18 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe } FIXME("WINHTTP_OPTION_CLIENT_CERT_CONTEXT\n"); return TRUE; + case WINHTTP_OPTION_ENABLE_FEATURE: + if(buflen == sizeof( DWORD ) && *(DWORD *)buffer == WINHTTP_ENABLE_SSL_REVOCATION) + { + request->check_revocation = TRUE; + SetLastError( NO_ERROR ); + return TRUE; + } + else + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_WINHTTP_INVALID_OPTION ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index c9e053fbea..2e903e1105 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -201,6 +201,37 @@ static void test_QueryOption(void) ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
+ feature = 0xdeadbeef; + size = sizeof(feature); + SetLastError(0xdeadbeef); + ret = WinHttpQueryOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, &size); + ok(!ret, "should fail to query enabled features for a request\n"); + ok(feature == 0xdeadbeef, "expect feature 0xdeadbeef, got %u\n", feature); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + + feature = WINHTTP_ENABLE_SSL_REVOCATION; + SetLastError(0xdeadbeef); + ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, 0, sizeof(feature)); + ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, 0); + ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature)); + ok(ret, "failed to set feature\n"); + ok(GetLastError() == NO_ERROR || broken(GetLastError() == 0xdeadbeef), /* Doesn't set error code on Vista or older */ + "expected NO_ERROR, got %u\n", GetLastError()); + + feature = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WinHttpSetOption(request, WINHTTP_OPTION_ENABLE_FEATURE, &feature, sizeof(feature)); + ok(!ret, "should fail to enable WINHTTP_ENABLE_SSL_REVOCATION with invalid parameters\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); + SetLastError(0xdeadbeef); ret = WinHttpCloseHandle(request); ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError()); diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index d639a2deb2..f1aa5622c6 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -210,6 +210,7 @@ typedef struct DWORD optional_len; netconn_t *netconn; DWORD security_flags; + BOOL check_revocation; const CERT_CONTEXT *server_cert; int resolve_timeout; int connect_timeout; @@ -306,7 +307,7 @@ void netconn_unload( void ) DECLSPEC_HIDDEN; ULONG netconn_query_data_available( netconn_t * ) DECLSPEC_HIDDEN; BOOL netconn_recv( netconn_t *, void *, size_t, int, int * ) DECLSPEC_HIDDEN; BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_storage *, int ) DECLSPEC_HIDDEN; -BOOL netconn_secure_connect( netconn_t *, WCHAR *, DWORD, CredHandle * ) DECLSPEC_HIDDEN; +BOOL netconn_secure_connect( netconn_t *, WCHAR *, DWORD, CredHandle *, BOOL ) DECLSPEC_HIDDEN; BOOL netconn_send( netconn_t *, const void *, size_t, int * ) DECLSPEC_HIDDEN; DWORD netconn_set_timeout( netconn_t *, BOOL, int ) DECLSPEC_HIDDEN; BOOL netconn_is_alive( netconn_t * ) DECLSPEC_HIDDEN;