Hans Leidekker : wininet: Always store the SSL context.
Alexandre Julliard
julliard at winehq.org
Wed Dec 11 13:05:46 CST 2013
Module: wine
Branch: master
Commit: 7ba776532d73a180130a33aee46e6182b535ce8e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7ba776532d73a180130a33aee46e6182b535ce8e
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Dec 11 10:49:34 2013 +0100
wininet: Always store the SSL context.
This allows applications to query certificate properties when verification has failed.
---
dlls/wininet/netconnection.c | 18 ++++++++----------
dlls/wininet/tests/http.c | 25 +++++++++++++++++++++++++
2 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index c90ef69..86c9b08 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -369,6 +369,7 @@ DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, BOOL m
netconn->security_flags = security_flags | server->security_flags;
netconn->mask_errors = mask_errors;
list_init(&netconn->pool_entry);
+ SecInvalidateHandle(&netconn->ssl_ctx);
result = create_netconn_socket(server, netconn, timeout);
if (result != ERROR_SUCCESS) {
@@ -407,7 +408,8 @@ void free_netconn(netconn_t *netconn)
heap_free(netconn->extra_buf);
netconn->extra_buf = NULL;
netconn->extra_len = 0;
- DeleteSecurityContext(&netconn->ssl_ctx);
+ if (SecIsValidHandle(&netconn->ssl_ctx))
+ DeleteSecurityContext(&netconn->ssl_ctx);
}
heap_free(netconn);
@@ -586,6 +588,10 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
TRACE("InitializeSecurityContext ret %08x\n", status);
if(status == SEC_E_OK) {
+ if(SecIsValidHandle(&connection->ssl_ctx))
+ DeleteSecurityContext(&connection->ssl_ctx);
+ connection->ssl_ctx = ctx;
+
if(in_bufs[1].BufferType == SECBUFFER_EXTRA)
FIXME("SECBUFFER_EXTRA not supported\n");
@@ -617,19 +623,14 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
}
}
-
if(status != SEC_E_OK || res != ERROR_SUCCESS) {
- WARN("Failed to initialize security context failed: %08x\n", status);
+ WARN("Failed to establish SSL connection: %08x (%u)\n", status, res);
heap_free(connection->ssl_buf);
connection->ssl_buf = NULL;
- DeleteSecurityContext(&ctx);
return res ? res : ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
}
-
TRACE("established SSL connection\n");
- connection->ssl_ctx = ctx;
-
connection->secure = TRUE;
connection->security_flags |= SECURITY_FLAG_SECURE;
@@ -963,9 +964,6 @@ LPCVOID NETCON_GetCert(netconn_t *connection)
const CERT_CONTEXT *ret;
SECURITY_STATUS res;
- if (!connection->secure)
- return NULL;
-
res = QueryContextAttributesW(&connection->ssl_ctx, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&ret);
return res == SEC_E_OK ? ret : NULL;
}
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index eb09bc7..951460f 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -4137,6 +4137,7 @@ static void _set_secflags(unsigned line, HINTERNET req, BOOL use_undoc, DWORD fl
static void test_security_flags(void)
{
+ INTERNET_CERTIFICATE_INFOA *cert;
HINTERNET ses, conn, req;
DWORD size, flags;
char buf[100];
@@ -4259,6 +4260,30 @@ static void test_security_flags(void)
ok(req_error == ERROR_INTERNET_SEC_CERT_REV_FAILED || broken(req_error == ERROR_INTERNET_SEC_CERT_ERRORS),
"req_error = %d\n", req_error);
+ size = 0;
+ res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, NULL, &size);
+ ok(res || GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InternetQueryOption failed: %d\n", GetLastError());
+ ok(size == sizeof(INTERNET_CERTIFICATE_INFOA), "size = %u\n", size);
+ cert = HeapAlloc(GetProcessHeap(), 0, size);
+ cert->lpszSubjectInfo = NULL;
+ cert->lpszIssuerInfo = NULL;
+ cert->lpszSignatureAlgName = (char *)0xdeadbeef;
+ cert->lpszEncryptionAlgName = (char *)0xdeadbeef;
+ cert->lpszProtocolName = (char *)0xdeadbeef;
+ cert->dwKeySize = 0xdeadbeef;
+ res = InternetQueryOptionW(req, INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, cert, &size);
+ ok(res, "InternetQueryOption failed: %u\n", GetLastError());
+ if (res)
+ {
+ ok(cert->lpszSubjectInfo && strlen(cert->lpszSubjectInfo) > 1, "expected a non-empty subject name\n");
+ ok(cert->lpszIssuerInfo && strlen(cert->lpszIssuerInfo) > 1, "expected a non-empty issuer name\n");
+ ok(!cert->lpszSignatureAlgName, "unexpected signature algorithm name\n");
+ ok(!cert->lpszEncryptionAlgName, "unexpected encryption algorithm name\n");
+ ok(!cert->lpszProtocolName, "unexpected protocol name\n");
+ ok(cert->dwKeySize != 0xdeadbeef, "unexpected key size\n");
+ }
+ HeapFree(GetProcessHeap(), 0, cert);
+
CHECK_NOTIFIED(INTERNET_STATUS_CONNECTING_TO_SERVER);
CHECK_NOTIFIED(INTERNET_STATUS_CONNECTED_TO_SERVER);
CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION);
More information about the wine-cvs
mailing list