Zhiyi Zhang : winhttp: Add support for WINHTTP_ENABLE_SSL_REVOCATION.

Alexandre Julliard julliard at winehq.org
Fri Aug 24 13:59:15 CDT 2018


Module: wine
Branch: master
Commit: b55f5683833059abfea714d59e4799204dcc39f4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b55f5683833059abfea714d59e4799204dcc39f4

Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date:   Fri Aug 24 16:32:49 2018 +0800

winhttp: Add support for WINHTTP_ENABLE_SSL_REVOCATION.

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 at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 d577a64..2625e4a 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 5e5b229..65d641f 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 fb81568..788f7c6 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 c9e053f..2e903e1 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 d639a2d..f1aa562 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;




More information about the wine-cvs mailing list