From: "Rémi Bernon" Subject: [PATCH 2/5] winhttp: Introduce new netconn_negotiate helper. Message-Id: <20210215114723.3898056-2-rbernon@codeweavers.com> Date: Mon, 15 Feb 2021 12:47:20 +0100 In-Reply-To: <20210215114723.3898056-1-rbernon@codeweavers.com> References: <20210215114723.3898056-1-rbernon@codeweavers.com> Signed-off-by: Rémi Bernon --- dlls/winhttp/net.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 46dc6bd21f0..2ba9b2dc65a 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -259,27 +259,22 @@ void netconn_close( struct netconn *conn ) heap_free(conn); } -DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, - BOOL check_revocation ) +static DWORD netconn_negotiate(struct netconn *conn, CredHandle *cred_handle, CtxtHandle *ctx_handle, WCHAR *hostname, + DWORD isc_req_flags, SecBufferDesc *init_desc, CtxtHandle *new_ctx_handle) { 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}; BYTE *read_buf; SIZE_T read_buf_size = 2048; ULONG attrs = 0; - CtxtHandle ctx; SSIZE_T size; - const CERT_CONTEXT *cert; SECURITY_STATUS status; - DWORD res = ERROR_SUCCESS; - - const DWORD isc_req_flags = ISC_REQ_ALLOCATE_MEMORY|ISC_REQ_USE_SESSION_KEY|ISC_REQ_CONFIDENTIALITY - |ISC_REQ_SEQUENCE_DETECT|ISC_REQ_REPLAY_DETECT|ISC_REQ_MANUAL_CRED_VALIDATION; if (!(read_buf = heap_alloc( read_buf_size ))) return ERROR_OUTOFMEMORY; - status = InitializeSecurityContextW(cred_handle, NULL, hostname, isc_req_flags, 0, 0, NULL, 0, - &ctx, &out_desc, &attrs, NULL); + status = InitializeSecurityContextW(cred_handle, ctx_handle, hostname, isc_req_flags, 0, 0, init_desc, + 0, new_ctx_handle, &out_desc, &attrs, NULL); + if (!ctx_handle) ctx_handle = new_ctx_handle; assert(status != SEC_E_OK); @@ -292,7 +287,7 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur size = sock_send(conn->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0); if(size != out_buf.cbBuffer) { ERR("send failed\n"); - res = ERROR_WINHTTP_SECURE_CHANNEL_ERROR; + status = ERROR_WINHTTP_SECURE_CHANNEL_ERROR; break; } @@ -338,7 +333,7 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur in_bufs[0].cbBuffer += size; in_bufs[0].pvBuffer = read_buf; - status = InitializeSecurityContextW(cred_handle, &ctx, hostname, isc_req_flags, 0, 0, &in_desc, + status = InitializeSecurityContextW(cred_handle, ctx_handle, hostname, isc_req_flags, 0, 0, &in_desc, 0, NULL, &out_desc, &attrs, NULL); TRACE("InitializeSecurityContext ret %08x\n", status); if(status == SEC_E_OK && in_bufs[1].BufferType == SECBUFFER_EXTRA) @@ -347,6 +342,21 @@ DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD secur heap_free(read_buf); + return status; +} + +DWORD netconn_secure_connect( struct netconn *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, + BOOL check_revocation ) +{ + CtxtHandle ctx; + const CERT_CONTEXT *cert; + SECURITY_STATUS status; + DWORD res = ERROR_SUCCESS; + + const DWORD isc_req_flags = ISC_REQ_ALLOCATE_MEMORY|ISC_REQ_USE_SESSION_KEY|ISC_REQ_CONFIDENTIALITY + |ISC_REQ_SEQUENCE_DETECT|ISC_REQ_REPLAY_DETECT|ISC_REQ_MANUAL_CRED_VALIDATION; + + status = netconn_negotiate(conn, cred_handle, NULL, hostname, isc_req_flags, NULL, &ctx); if(status != SEC_E_OK) goto failed; -- 2.30.0