Damjan Jovanovic : secur32: Implement the SECPKG_ATTR_UNIQUE_BINDINGS context attribute.
Alexandre Julliard
julliard at winehq.org
Thu Jan 28 15:41:41 CST 2021
Module: wine
Branch: master
Commit: de9238962c237f0d4463199a0a1f9f6b6835aed5
URL: https://source.winehq.org/git/wine.git/?a=commit;h=de9238962c237f0d4463199a0a1f9f6b6835aed5
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Thu Jan 28 19:02:39 2021 +0200
secur32: Implement the SECPKG_ATTR_UNIQUE_BINDINGS context attribute.
.NET's System.Data.SqlClient needs this to connect to MSSQL Server.
Signed-off-by: Damjan Jovanovic <damjan.jov at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/secur32/schannel.c | 7 +++++++
dlls/secur32/schannel_gnutls.c | 37 +++++++++++++++++++++++++++++++++++++
dlls/secur32/schannel_macosx.c | 7 +++++++
dlls/secur32/secur32_priv.h | 2 ++
dlls/secur32/tests/schannel.c | 26 ++++++++++++++++++++++++++
5 files changed, 79 insertions(+)
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index e76a3e46c34..2d135a85227 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -1115,6 +1115,11 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesW(
memcpy(p, hash, hash_size);
return SEC_E_OK;
}
+ case SECPKG_ATTR_UNIQUE_BINDINGS:
+ {
+ SecPkgContext_Bindings *bindings = buffer;
+ return schan_imp_get_unique_channel_binding(ctx->session, bindings);
+ }
case SECPKG_ATTR_APPLICATION_PROTOCOL:
{
SecPkgContext_ApplicationProtocol *protocol = buffer;
@@ -1154,6 +1159,8 @@ static SECURITY_STATUS SEC_ENTRY schan_QueryContextAttributesA(
return schan_QueryContextAttributesW(context_handle, attribute, buffer);
case SECPKG_ATTR_ENDPOINT_BINDINGS:
return schan_QueryContextAttributesW(context_handle, attribute, buffer);
+ case SECPKG_ATTR_UNIQUE_BINDINGS:
+ return schan_QueryContextAttributesW(context_handle, attribute, buffer);
case SECPKG_ATTR_APPLICATION_PROTOCOL:
return schan_QueryContextAttributesW(context_handle, attribute, buffer);
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index 784c1ffe6e8..e342df3874d 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -95,6 +95,7 @@ MAKE_FUNCPTR(gnutls_record_get_max_size);
MAKE_FUNCPTR(gnutls_record_recv);
MAKE_FUNCPTR(gnutls_record_send);
MAKE_FUNCPTR(gnutls_server_name_set);
+MAKE_FUNCPTR(gnutls_session_channel_binding);
MAKE_FUNCPTR(gnutls_transport_get_ptr);
MAKE_FUNCPTR(gnutls_transport_set_errno);
MAKE_FUNCPTR(gnutls_transport_set_ptr);
@@ -507,6 +508,41 @@ SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
return SEC_E_OK;
}
+SECURITY_STATUS schan_imp_get_unique_channel_binding(schan_imp_session session,
+ SecPkgContext_Bindings *bindings)
+{
+ static const char prefix[] = "tls-unique:";
+ gnutls_datum_t datum;
+ int rc;
+ SECURITY_STATUS ret;
+ char *p;
+ gnutls_session_t s = (gnutls_session_t)session;
+
+ rc = pgnutls_session_channel_binding(s, GNUTLS_CB_TLS_UNIQUE, &datum);
+ if (rc)
+ {
+ pgnutls_perror(rc);
+ return SEC_E_INTERNAL_ERROR;
+ }
+
+ bindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + sizeof(prefix)-1 + datum.size;
+ bindings->Bindings = heap_alloc_zero(bindings->BindingsLength);
+ if (!bindings->Bindings)
+ ret = SEC_E_INSUFFICIENT_MEMORY;
+ else
+ {
+ bindings->Bindings->cbApplicationDataLength = sizeof(prefix)-1 + datum.size;
+ bindings->Bindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS);
+ p = (char*)(bindings->Bindings+1);
+ memcpy(p, prefix, sizeof(prefix)-1);
+ p += sizeof(prefix)-1;
+ memcpy(p, datum.data, datum.size);
+ ret = SEC_E_OK;
+ }
+ free(datum.data);
+ return ret;
+}
+
ALG_ID schan_imp_get_key_signature_algorithm(schan_imp_session session)
{
gnutls_session_t s = (gnutls_session_t)session;
@@ -1032,6 +1068,7 @@ BOOL schan_imp_init(void)
LOAD_FUNCPTR(gnutls_record_recv);
LOAD_FUNCPTR(gnutls_record_send);
LOAD_FUNCPTR(gnutls_server_name_set)
+ LOAD_FUNCPTR(gnutls_session_channel_binding)
LOAD_FUNCPTR(gnutls_transport_get_ptr)
LOAD_FUNCPTR(gnutls_transport_set_errno)
LOAD_FUNCPTR(gnutls_transport_set_ptr)
diff --git a/dlls/secur32/schannel_macosx.c b/dlls/secur32/schannel_macosx.c
index d725c9d22c2..6e6296722cc 100644
--- a/dlls/secur32/schannel_macosx.c
+++ b/dlls/secur32/schannel_macosx.c
@@ -1039,6 +1039,13 @@ SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
return SEC_E_OK;
}
+SECURITY_STATUS schan_imp_get_unique_channel_binding(schan_imp_session session,
+ SecPkgContext_Bindings *bindings)
+{
+ FIXME("SECPKG_ATTR_UNIQUE_BINDINGS is unsupported on MacOS\n");
+ return SEC_E_UNSUPPORTED_FUNCTION;
+}
+
#ifndef HAVE_SSLCOPYPEERCERTIFICATES
static void schan_imp_cf_release(const void *arg, void *ctx)
{
diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h
index c34d1d32566..ce8d55d1eb6 100644
--- a/dlls/secur32/secur32_priv.h
+++ b/dlls/secur32/secur32_priv.h
@@ -237,6 +237,8 @@ extern unsigned int schan_imp_get_max_message_size(schan_imp_session session) DE
extern ALG_ID schan_imp_get_key_signature_algorithm(schan_imp_session session) DECLSPEC_HIDDEN;
extern SECURITY_STATUS schan_imp_get_connection_info(schan_imp_session session,
SecPkgContext_ConnectionInfo *info) DECLSPEC_HIDDEN;
+extern SECURITY_STATUS schan_imp_get_unique_channel_binding(schan_imp_session session,
+ SecPkgContext_Bindings *bindings) DECLSPEC_HIDDEN;
extern SECURITY_STATUS schan_imp_get_session_peer_certificate(schan_imp_session session, HCERTSTORE,
PCCERT_CONTEXT *cert) DECLSPEC_HIDDEN;
extern SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c
index 30022437bc0..99adf0bbc19 100644
--- a/dlls/secur32/tests/schannel.c
+++ b/dlls/secur32/tests/schannel.c
@@ -925,6 +925,32 @@ todo_wine
win_skip("SECPKG_ATTR_ENDPOINT_BINDINGS not supported\n");
}
+ status = pQueryContextAttributesA(&context, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings);
+ ok(status == SEC_E_OK || broken(status == SEC_E_UNSUPPORTED_FUNCTION),
+ "QueryContextAttributesW(SECPKG_ATTR_UNIQUE_BINDINGS) failed: %08x\n", status);
+ if(status == SEC_E_OK) {
+ const char *p;
+ static const char prefix[] = "tls-unique:";
+
+ ok(bindings.BindingsLength > sizeof(*bindings.Bindings) + sizeof(prefix)-1,
+ "bindings.BindingsLength = %u\n", bindings.BindingsLength);
+ ok(!bindings.Bindings->dwInitiatorAddrType, "dwInitiatorAddrType = %x\n", bindings.Bindings->dwInitiatorAddrType);
+ ok(!bindings.Bindings->cbInitiatorLength, "cbInitiatorLength = %x\n", bindings.Bindings->cbInitiatorLength);
+ ok(!bindings.Bindings->dwInitiatorOffset, "dwInitiatorOffset = %x\n", bindings.Bindings->dwInitiatorOffset);
+ ok(!bindings.Bindings->dwAcceptorAddrType, "dwAcceptorAddrType = %x\n", bindings.Bindings->dwAcceptorAddrType);
+ ok(!bindings.Bindings->cbAcceptorLength, "cbAcceptorLength = %x\n", bindings.Bindings->cbAcceptorLength);
+ ok(!bindings.Bindings->dwAcceptorOffset, "dwAcceptorOffset = %x\n", bindings.Bindings->dwAcceptorOffset);
+ ok(sizeof(*bindings.Bindings) + bindings.Bindings->cbApplicationDataLength == bindings.BindingsLength,
+ "cbApplicationDataLength = %x\n", bindings.Bindings->cbApplicationDataLength);
+ ok(bindings.Bindings->dwApplicationDataOffset == sizeof(*bindings.Bindings),
+ "dwApplicationDataOffset = %x\n", bindings.Bindings->dwApplicationDataOffset);
+ p = (const char*)(bindings.Bindings+1);
+ ok(!memcmp(p, prefix, sizeof(prefix)-1), "wrong prefix\n");
+ FreeContextBuffer(bindings.Bindings);
+ } else {
+ win_skip("SECPKG_ATTR_UNIQUE_BINDINGS not supported\n");
+ }
+
CertFreeCertificateContext(cert);
}
More information about the wine-cvs
mailing list