Hans Leidekker : winhttp: Store the server certificate context in the request.

Alexandre Julliard julliard at winehq.org
Mon Jun 11 13:10:51 CDT 2018


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Jun 11 09:20:35 2018 +0200

winhttp: Store the server certificate context in the request.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winhttp/net.c             |  1 -
 dlls/winhttp/request.c         | 11 +++++++++++
 dlls/winhttp/session.c         | 14 ++++++--------
 dlls/winhttp/tests/winhttp.c   |  5 +++++
 dlls/winhttp/winhttp_private.h |  2 ++
 5 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index d0d02d5..d577a64 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -47,7 +47,6 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winhttp.h"
-#include "wincrypt.h"
 #include "schannel.h"
 
 #include "winhttp_private.h"
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 96a2c91..56ec910 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -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;
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index e2b91fa..fb81568 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -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;
     }
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index 302974c..4b4a84c 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -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);
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index 0eb0dea..d639a2d 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -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;




More information about the wine-cvs mailing list