diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index 9ac7223bb..527f69ba0 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -23,6 +23,9 @@ #include "crypto.h" #include "certificate.h" +#include +#include + #include #include @@ -40,6 +43,7 @@ struct rdp_tls BYTE* PublicKey; DWORD PublicKeyLength; rdpSettings* settings; + SecPkgContext_Bindings* Bindings; rdpCertificateStore* certificate_store; }; diff --git a/libfreerdp/core/gateway/ncacn_http.c b/libfreerdp/core/gateway/ncacn_http.c index 4020a844f..4e3489d81 100644 --- a/libfreerdp/core/gateway/ncacn_http.c +++ b/libfreerdp/core/gateway/ncacn_http.c @@ -80,7 +80,7 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc) content_length = (continue_needed) ? 0 : 0x40000000; - s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_IN); + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], content_length, TSG_CHANNEL_IN); DEBUG_RPC("\n%s", Stream_Buffer(s)); rpc_in_write(rpc, Stream_Buffer(s), Stream_Length(s)); @@ -102,8 +102,8 @@ int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); - ntlm->inputBuffer.pvBuffer = ntlm_token_data; - ntlm->inputBuffer.cbBuffer = ntlm_token_length; + ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; + ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(http_response); @@ -123,7 +123,8 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel) ntlm = rpc->NtlmHttpOut->ntlm; ntlm_client_init(ntlm, TRUE, settings->GatewayUsername, - settings->GatewayDomain, settings->GatewayPassword); + settings->GatewayDomain, settings->GatewayPassword, + rpc->TlsIn->Bindings); //ntlm_client_make_spn(ntlm, NULL, settings->GatewayHostname); ntlm_client_make_spn(ntlm, _T("HTTP"), settings->GatewayHostname); @@ -168,7 +169,7 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc) content_length = (continue_needed) ? 0 : 76; - s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_OUT); + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], content_length, TSG_CHANNEL_OUT); DEBUG_RPC("\n%s", Stream_Buffer(s)); rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s)); @@ -190,8 +191,8 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc) crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); - ntlm->inputBuffer.pvBuffer = ntlm_token_data; - ntlm->inputBuffer.cbBuffer = ntlm_token_length; + ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; + ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(http_response); diff --git a/libfreerdp/core/gateway/ntlm.c b/libfreerdp/core/gateway/ntlm.c index 656a89230..75ba9bcf1 100644 --- a/libfreerdp/core/gateway/ntlm.c +++ b/libfreerdp/core/gateway/ntlm.c @@ -37,12 +37,15 @@ #include "ntlm.h" -BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password) +BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password, SecPkgContext_Bindings* Bindings) { SECURITY_STATUS status; sspi_GlobalInit(); + ntlm->http = http; + ntlm->Bindings = Bindings; + #ifdef WITH_NATIVE_SSPI { HMODULE hSSPI; @@ -91,7 +94,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* ntlm->fContextReq = 0; - if (http) + if (ntlm->http) { /* flags for HTTP authentication */ ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY; @@ -195,25 +198,33 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) { SECURITY_STATUS status; - if (ntlm->outputBuffer.pvBuffer) + if (ntlm->outputBuffer[0].pvBuffer) { - free(ntlm->outputBuffer.pvBuffer); - ntlm->outputBuffer.pvBuffer = NULL; + free(ntlm->outputBuffer[0].pvBuffer); + ntlm->outputBuffer[0].pvBuffer = NULL; } ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION; ntlm->outputBufferDesc.cBuffers = 1; - ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer; - ntlm->outputBuffer.BufferType = SECBUFFER_TOKEN; - ntlm->outputBuffer.cbBuffer = ntlm->cbMaxToken; - ntlm->outputBuffer.pvBuffer = malloc(ntlm->outputBuffer.cbBuffer); + ntlm->outputBufferDesc.pBuffers = ntlm->outputBuffer; + ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN; + ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken; + ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer); if (ntlm->haveInputBuffer) { ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION; ntlm->inputBufferDesc.cBuffers = 1; - ntlm->inputBufferDesc.pBuffers = &ntlm->inputBuffer; - ntlm->inputBuffer.BufferType = SECBUFFER_TOKEN; + ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer; + ntlm->inputBuffer[0].BufferType = SECBUFFER_TOKEN; + + if (ntlm->Bindings) + { + ntlm->inputBufferDesc.cBuffers++; + ntlm->inputBuffer[1].BufferType = SECBUFFER_CHANNEL_BINDINGS; + ntlm->inputBuffer[1].cbBuffer = ntlm->Bindings->BindingsLength; + ntlm->inputBuffer[1].pvBuffer = (void*) ntlm->Bindings->Bindings; + } } status = ntlm->table->InitializeSecurityContext(&ntlm->credentials, @@ -243,7 +254,7 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) if (ntlm->haveInputBuffer) { - free(ntlm->inputBuffer.pvBuffer); + free(ntlm->inputBuffer[0].pvBuffer); } ntlm->haveInputBuffer = TRUE; diff --git a/libfreerdp/core/gateway/ntlm.h b/libfreerdp/core/gateway/ntlm.h index 1d2b2d38e..845e0ad68 100644 --- a/libfreerdp/core/gateway/ntlm.h +++ b/libfreerdp/core/gateway/ntlm.h @@ -43,14 +43,15 @@ typedef struct rdp_ntlm_http rdpNtlmHttp; struct rdp_ntlm { + BOOL http; CtxtHandle context; ULONG cbMaxToken; ULONG fContextReq; ULONG pfContextAttr; TimeStamp expiration; PSecBuffer pBuffer; - SecBuffer inputBuffer; - SecBuffer outputBuffer; + SecBuffer inputBuffer[2]; + SecBuffer outputBuffer[2]; BOOL haveContext; BOOL haveInputBuffer; LPTSTR ServicePrincipalName; @@ -62,6 +63,7 @@ struct rdp_ntlm SecurityFunctionTable* table; SEC_WINNT_AUTH_IDENTITY identity; SecPkgContext_Sizes ContextSizes; + SecPkgContext_Bindings* Bindings; }; struct rdp_ntlm_http @@ -72,7 +74,8 @@ struct rdp_ntlm_http BOOL ntlm_authenticate(rdpNtlm* ntlm); -BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* domain, char* password); +BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, + char* domain, char* password, SecPkgContext_Bindings* Bindings); void ntlm_client_uninit(rdpNtlm* ntlm); BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname); diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index 9c01eb4c8..d524ff0d5 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -102,7 +102,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc) rpc->ntlm = ntlm_new(); - ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword); + ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword, NULL); ntlm_client_make_spn(rpc->ntlm, NULL, settings->GatewayHostname); ntlm_authenticate(rpc->ntlm); @@ -112,8 +112,8 @@ int rpc_send_bind_pdu(rdpRpc* rpc) rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) bind_pdu); - bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer; - bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer; + bind_pdu->auth_length = rpc->ntlm->outputBuffer[0].cbBuffer; + bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].pvBuffer; bind_pdu->ptype = PTYPE_BIND; bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_SUPPORT_HEADER_SIGN | PFC_CONC_MPX; @@ -228,11 +228,11 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) rpc->max_recv_frag = header->bind_ack.max_xmit_frag; rpc->max_xmit_frag = header->bind_ack.max_recv_frag; - rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length; - rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length); + rpc->ntlm->inputBuffer[0].cbBuffer = header->common.auth_length; + rpc->ntlm->inputBuffer[0].pvBuffer = malloc(header->common.auth_length); auth_data = buffer + (header->common.frag_length - header->common.auth_length); - CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length); + CopyMemory(rpc->ntlm->inputBuffer[0].pvBuffer, auth_data, header->common.auth_length); ntlm_authenticate(rpc->ntlm); @@ -261,8 +261,8 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) auth_3_pdu); - auth_3_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer; - auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer; + auth_3_pdu->auth_length = rpc->ntlm->outputBuffer[0].cbBuffer; + auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].pvBuffer; auth_3_pdu->ptype = PTYPE_RPC_AUTH_3; auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX; diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 6b265fb27..7269304fa 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -22,6 +22,7 @@ #endif #include +#include #include #include @@ -58,6 +59,86 @@ static void tls_free_certificate(CryptoCert cert) free(cert); } +static void tls_md5_update_uint32_be(MD5_CTX* md5, UINT32 num) +{ + BYTE be32[4]; + + be32[0] = (num >> 0) & 0xFF; + be32[1] = (num >> 8) & 0xFF; + be32[2] = (num >> 16) & 0xFF; + be32[3] = (num >> 24) & 0xFF; + + MD5_Update(md5, be32, 4); +} + +BYTE* tls_get_channel_bindings_hash(SecPkgContext_Bindings* Bindings) +{ + MD5_CTX md5; + BYTE* ChannelBindingToken; + UINT32 ChannelBindingTokenLength; + BYTE* ChannelBindingsHash; + UINT32 ChannelBindingsHashLength; + SEC_CHANNEL_BINDINGS* ChannelBindings; + + ChannelBindings = Bindings->Bindings; + ChannelBindingTokenLength = Bindings->BindingsLength - sizeof(SEC_CHANNEL_BINDINGS); + ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; + + ChannelBindingsHashLength = 16; + ChannelBindingsHash = (BYTE*) malloc(ChannelBindingsHashLength); + ZeroMemory(ChannelBindingsHash, ChannelBindingsHashLength); + + MD5_Init(&md5); + + tls_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType); + tls_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength); + tls_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType); + tls_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength); + tls_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength); + + MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); + + MD5_Final(ChannelBindingsHash, &md5); + + return ChannelBindingsHash; +} + +#define TLS_SERVER_END_POINT "tls-server-end-point:" + +SecPkgContext_Bindings* tls_get_channel_bindings(X509* cert) +{ + int PrefixLength; + BYTE CertificateHash[32]; + UINT32 CertificateHashLength; + BYTE* ChannelBindingToken; + UINT32 ChannelBindingTokenLength; + SEC_CHANNEL_BINDINGS* ChannelBindings; + SecPkgContext_Bindings* ContextBindings; + + ZeroMemory(CertificateHash, sizeof(CertificateHash)); + X509_digest(cert, EVP_sha256(), CertificateHash, &CertificateHashLength); + + PrefixLength = strlen(TLS_SERVER_END_POINT); + ChannelBindingTokenLength = PrefixLength + CertificateHashLength; + + ContextBindings = (SecPkgContext_Bindings*) malloc(sizeof(SecPkgContext_Bindings)); + ZeroMemory(ContextBindings, sizeof(SecPkgContext_Bindings)); + + ContextBindings->BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + ChannelBindingTokenLength; + ChannelBindings = (SEC_CHANNEL_BINDINGS*) malloc(ContextBindings->BindingsLength); + ZeroMemory(ChannelBindings, ContextBindings->BindingsLength); + ContextBindings->Bindings = ChannelBindings; + + ChannelBindings->cbApplicationDataLength = ChannelBindingTokenLength; + ChannelBindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS); + ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; + + strcpy((char*) ChannelBindingToken, TLS_SERVER_END_POINT); + CopyMemory(&ChannelBindingToken[PrefixLength], CertificateHash, CertificateHashLength); + + return ContextBindings; +} + BOOL tls_connect(rdpTls* tls) { CryptoCert cert; @@ -135,6 +216,8 @@ BOOL tls_connect(rdpTls* tls) return FALSE; } + tls->Bindings = tls_get_channel_bindings(cert->px509); + if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) { printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 41c537898..5ffff741b 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -416,8 +416,9 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredenti NTLM_CONTEXT* context; SECURITY_STATUS status; CREDENTIALS* credentials; - PSecBuffer input_buffer; - PSecBuffer output_buffer; + PSecBuffer input_buffer = NULL; + PSecBuffer output_buffer = NULL; + PSecBuffer channel_bindings = NULL; context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); @@ -478,6 +479,18 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredenti if (input_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; + if (pInput->cBuffers > 1) + { + if (pInput->pBuffers[1].BufferType == SECBUFFER_CHANNEL_BINDINGS) + channel_bindings = &pInput->pBuffers[1]; + } + + if (channel_bindings) + { + context->Bindings.BindingsLength = channel_bindings->cbBuffer; + context->Bindings.Bindings = (SEC_CHANNEL_BINDINGS*) channel_bindings->pvBuffer; + } + if (context->state == NTLM_STATE_CHALLENGE) { status = ntlm_read_ChallengeMessage(context, input_buffer); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.h b/winpr/libwinpr/sspi/NTLM/ntlm.h index f0146b7d6..1c8ad520b 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.h +++ b/winpr/libwinpr/sspi/NTLM/ntlm.h @@ -243,7 +243,7 @@ struct _NTLM_CONTEXT SEC_WINNT_AUTH_IDENTITY identity; BYTE* ChannelBindingToken; BYTE ChannelBindingsHash[16]; - SecPkgContext_Bindings EndpointBindings; + SecPkgContext_Bindings Bindings; SecBuffer NegotiateMessage; SecBuffer ChallengeMessage; SecBuffer AuthenticateMessage; diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 8f08d11a7..bfa2d91c8 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -228,66 +228,6 @@ void ntlm_free_unicode_string(PUNICODE_STRING string) * https://raw.github.com/mozilla/mozilla-central/master/extensions/auth/nsAuthSSPI.cpp */ -/* Certificate */ - -BYTE test_Certificate[525] = - "\x30\x82\x02\x09\x30\x82\x01\x76\xa0\x03\x02\x01\x02\x02\x10\xcb" - "\x69\x79\xcd\x51\x75\xc5\xb7\x4b\x67\x30\x83\x6c\x78\x44\x27\x30" - "\x09\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x30\x16\x31\x14\x30\x12" - "\x06\x03\x55\x04\x03\x13\x0b\x44\x43\x2d\x57\x53\x32\x30\x30\x38" - "\x52\x32\x30\x1e\x17\x0d\x31\x32\x31\x31\x31\x37\x30\x30\x35\x39" - "\x32\x31\x5a\x17\x0d\x33\x39\x31\x32\x33\x31\x32\x33\x35\x39\x35" - "\x39\x5a\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13\x0b\x44" - "\x43\x2d\x57\x53\x32\x30\x30\x38\x52\x32\x30\x81\x9f\x30\x0d\x06" - "\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x81\x8d\x00" - "\x30\x81\x89\x02\x81\x81\x00\x9b\x00\xf8\x1a\x2d\x37\xc6\x8d\xa1" - "\x39\x91\x46\xf3\x6a\x1b\xf9\x60\x6c\xb3\x6c\xa0\xac\xed\x85\xe0" - "\x3f\xdc\x92\x86\x36\xbd\x64\xbf\x36\x51\xdb\x57\x3a\x8a\x82\x6b" - "\xd8\x94\x17\x7b\xd3\x91\x11\x98\xef\x19\x06\x52\x30\x03\x73\x67" - "\xc8\xed\x8e\xfa\x0b\x3d\x4c\xc9\x10\x63\x9f\xcf\xb4\xcf\x39\xd8" - "\xfe\x99\xeb\x5b\x11\xf2\xfc\xfa\x86\x24\xd9\xff\xd9\x19\xf5\x69" - "\xb4\xdf\x5a\x5a\xc4\x94\xb4\xb0\x07\x25\x97\x13\xad\x7e\x38\x14" - "\xfb\xd6\x33\x65\x6f\xe6\xf7\x48\x4b\x2d\xb3\x51\x2e\x6d\xc7\xea" - "\x11\x76\x9a\x2b\xf0\x00\x4d\x02\x03\x01\x00\x01\xa3\x60\x30\x5e" - "\x30\x13\x06\x03\x55\x1d\x25\x04\x0c\x30\x0a\x06\x08\x2b\x06\x01" - "\x05\x05\x07\x03\x01\x30\x47\x06\x03\x55\x1d\x01\x04\x40\x30\x3e" - "\x80\x10\xeb\x65\x26\x03\x95\x4b\xd6\xc0\x54\x75\x78\x7c\xb6\x2a" - "\xa1\xbb\xa1\x18\x30\x16\x31\x14\x30\x12\x06\x03\x55\x04\x03\x13" - "\x0b\x44\x43\x2d\x57\x53\x32\x30\x30\x38\x52\x32\x82\x10\xcb\x69" - "\x79\xcd\x51\x75\xc5\xb7\x4b\x67\x30\x83\x6c\x78\x44\x27\x30\x09" - "\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x03\x81\x81\x00\x7b\xfa\xfe" - "\xee\x74\x05\xac\xbb\x79\xe9\xda\xca\x00\x44\x96\x94\x71\x92\xb1" - "\xdb\xc9\x9b\x71\x29\xc0\xe4\x28\x5e\x6a\x50\x99\xcd\xa8\x17\xe4" - "\x56\xb9\xef\x7f\x02\x7d\x96\xa3\x48\x14\x72\x75\x2f\xb0\xb5\x87" - "\xee\x55\xe9\x6a\x6d\x28\x3c\xc1\xfd\x00\xe4\x76\xe3\x80\x88\x78" - "\x26\x0d\x6c\x8c\xb8\x64\x61\x63\xb7\x13\x3a\xab\xc7\xdd\x1d\x0a" - "\xd7\x15\x45\xa1\xd6\xd9\x34\xc7\x21\x48\xfb\x43\x87\x38\xda\x1f" - "\x50\x47\xb1\xa5\x5c\x47\xed\x04\x44\x97\xd3\xac\x74\x2d\xeb\x09" - "\x77\x59\xbf\xa3\x54\x5b\xde\x42\xd5\x23\x5a\x71\x9f"; - -BYTE test_CertificateHash_SHA256[] = - "\xea\x05\xfe\xfe\xcc\x6b\x0b\xd5\x71\xdb\xbc\x5b\xaa\x3e\xd4\x53" - "\x86\xd0\x44\x68\x35\xf7\xb7\x4c\x85\x62\x1b\x99\x83\x47\x5f\x95"; - -BYTE test_ChannelBindingsHash[] = - "\x65\x86\xE9\x9D\x81\xC2\xFC\x98\x4E\x47\x17\x2F\xD4\xDD\x03\x10"; - -/* - * Channel Bindings Data: - * - * tls-server-end-point: - */ - -char TlsServerEndPointPrefix[] = "tls-server-end-point:"; - -void ntlm_uint32_to_big_endian(UINT32 num, BYTE be32[4]) -{ - be32[0] = (num >> 0) & 0xFF; - be32[1] = (num >> 8) & 0xFF; - be32[2] = (num >> 16) & 0xFF; - be32[3] = (num >> 24) & 0xFF; -} - /* typedef struct gss_channel_bindings_struct { OM_uint32 initiator_addrtype; @@ -298,83 +238,45 @@ typedef struct gss_channel_bindings_struct { } *gss_channel_bindings_t; */ +static void ntlm_md5_update_uint32_be(MD5_CTX* md5, UINT32 num) +{ + BYTE be32[4]; + + be32[0] = (num >> 0) & 0xFF; + be32[1] = (num >> 8) & 0xFF; + be32[2] = (num >> 16) & 0xFF; + be32[3] = (num >> 24) & 0xFF; + + MD5_Update(md5, be32, 4); +} + void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) { -#if 0 MD5_CTX md5; - BYTE be32[4]; - int PrefixLength; - SHA256_CTX sha256; - BYTE* CertificateHash; - int CertificateHashLength; - BYTE* pChannelBindingToken; - int ChannelBindingTokenLength; + BYTE* ChannelBindingToken; + UINT32 ChannelBindingTokenLength; SEC_CHANNEL_BINDINGS* ChannelBindings; ZeroMemory(context->ChannelBindingsHash, 16); + ChannelBindings = context->Bindings.Bindings; - CertificateHashLength = 32; - CertificateHash = (BYTE*) malloc(CertificateHashLength); - ZeroMemory(CertificateHash, CertificateHashLength); + if (!ChannelBindings) + return; - SHA256_Init(&sha256); - SHA256_Update(&sha256, test_Certificate, sizeof(test_Certificate)); - SHA256_Final(CertificateHash, &sha256); - - printf("Certificate SHA256 Hash:\n"); - winpr_HexDump(CertificateHash, CertificateHashLength); - - PrefixLength = strlen(TlsServerEndPointPrefix); - ChannelBindingTokenLength = PrefixLength + CertificateHashLength; - context->ChannelBindingToken = (BYTE*) malloc(ChannelBindingTokenLength + 1); - strcpy((char*) context->ChannelBindingToken, TlsServerEndPointPrefix); - CopyMemory(&context->ChannelBindingToken[PrefixLength], CertificateHash, CertificateHashLength); - - printf("ChannelBindingToken:\n"); - winpr_HexDump(context->ChannelBindingToken, ChannelBindingTokenLength); - - context->EndpointBindings.BindingsLength = sizeof(SEC_CHANNEL_BINDINGS) + ChannelBindingTokenLength; - context->EndpointBindings.Bindings = (SEC_CHANNEL_BINDINGS*) malloc(context->EndpointBindings.BindingsLength); - ZeroMemory(context->EndpointBindings.Bindings, context->EndpointBindings.BindingsLength); - - ChannelBindings = context->EndpointBindings.Bindings; - ChannelBindings->cbApplicationDataLength = ChannelBindingTokenLength; - ChannelBindings->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS); - - pChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; - CopyMemory(pChannelBindingToken, context->ChannelBindingToken, ChannelBindingTokenLength); - - printf("ChannelBindings\n"); - winpr_HexDump((BYTE*) ChannelBindings, context->EndpointBindings.BindingsLength); + ChannelBindingTokenLength = context->Bindings.BindingsLength - sizeof(SEC_CHANNEL_BINDINGS); + ChannelBindingToken = &((BYTE*) ChannelBindings)[ChannelBindings->dwApplicationDataOffset]; MD5_Init(&md5); - ntlm_uint32_to_big_endian(ChannelBindings->dwInitiatorAddrType, be32); - MD5_Update(&md5, be32, 4); + ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwInitiatorAddrType); + ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbInitiatorLength); + ntlm_md5_update_uint32_be(&md5, ChannelBindings->dwAcceptorAddrType); + ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbAcceptorLength); + ntlm_md5_update_uint32_be(&md5, ChannelBindings->cbApplicationDataLength); - ntlm_uint32_to_big_endian(ChannelBindings->cbInitiatorLength, be32); - MD5_Update(&md5, be32, 4); - - ntlm_uint32_to_big_endian(ChannelBindings->dwAcceptorAddrType, be32); - MD5_Update(&md5, be32, 4); - - ntlm_uint32_to_big_endian(ChannelBindings->cbAcceptorLength, be32); - MD5_Update(&md5, be32, 4); - - ntlm_uint32_to_big_endian(ChannelBindings->cbApplicationDataLength, be32); - MD5_Update(&md5, be32, 4); - - MD5_Update(&md5, (void*) pChannelBindingToken, ChannelBindingTokenLength); + MD5_Update(&md5, (void*) ChannelBindingToken, ChannelBindingTokenLength); MD5_Final(context->ChannelBindingsHash, &md5); - - printf("ChannelBindingsHash:\n"); - winpr_HexDump(context->ChannelBindingsHash, 16); - - free(CertificateHash); - - printf("\n\n"); -#endif } void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context)