From a1355135c5aa5e07f991668e996c89459779e9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 27 Jun 2012 11:10:17 +0200 Subject: [PATCH] libfreerdp-crypto: fix server-side NLA with certificate store --- libfreerdp-crypto/nla.c | 57 ++++++++++++++++++++++++++++++++++++----- libfreerdp-crypto/tls.c | 18 ++----------- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/libfreerdp-crypto/nla.c b/libfreerdp-crypto/nla.c index df87c2232..22dcef76f 100644 --- a/libfreerdp-crypto/nla.c +++ b/libfreerdp-crypto/nla.c @@ -519,7 +519,11 @@ int credssp_server_authenticate(rdpCredssp* credssp) return 0; } - credssp_decrypt_public_key_echo(credssp); + if (credssp_decrypt_public_key_echo(credssp) != SEC_E_OK) + { + printf("Error: could not verify client's public key echo\n"); + return -1; + } sspi_SecBufferFree(&credssp->negoToken); credssp->negoToken.pvBuffer = NULL; @@ -599,28 +603,69 @@ int credssp_authenticate(rdpCredssp* credssp) return credssp_client_authenticate(credssp); } +void ap_integer_increment_le(BYTE* number, int size) +{ + int index; + + for (index = 0; index < size; index++) + { + if (number[index] < 0xFF) + { + number[index]++; + break; + } + else + { + number[index] = 0; + continue; + } + } +} + +void ap_integer_decrement_le(BYTE* number, int size) +{ + int index; + + for (index = 0; index < size; index++) + { + if (number[index] > 0) + { + number[index]--; + break; + } + else + { + number[index] = 0xFF; + continue; + } + } +} + SECURITY_STATUS credssp_encrypt_public_key_echo(rdpCredssp* credssp) { SecBuffer Buffers[2]; SecBufferDesc Message; SECURITY_STATUS status; + int public_key_length; + + public_key_length = credssp->PublicKey.cbBuffer; Buffers[0].BufferType = SECBUFFER_TOKEN; /* Signature */ Buffers[1].BufferType = SECBUFFER_DATA; /* TLS Public Key */ - sspi_SecBufferAlloc(&credssp->pubKeyAuth, credssp->ContextSizes.cbMaxSignature + credssp->PublicKey.cbBuffer); + sspi_SecBufferAlloc(&credssp->pubKeyAuth, credssp->ContextSizes.cbMaxSignature + public_key_length); Buffers[0].cbBuffer = credssp->ContextSizes.cbMaxSignature; Buffers[0].pvBuffer = credssp->pubKeyAuth.pvBuffer; - Buffers[1].cbBuffer = credssp->PublicKey.cbBuffer; + Buffers[1].cbBuffer = public_key_length; Buffers[1].pvBuffer = ((BYTE*) credssp->pubKeyAuth.pvBuffer) + credssp->ContextSizes.cbMaxSignature; CopyMemory(Buffers[1].pvBuffer, credssp->PublicKey.pvBuffer, Buffers[1].cbBuffer); if (credssp->server) { /* server echos the public key +1 */ - ((BYTE*) Buffers[1].pvBuffer)[0]++; + ap_integer_increment_le((BYTE*) Buffers[1].pvBuffer, Buffers[1].cbBuffer); } Message.cBuffers = 2; @@ -689,7 +734,7 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) if (!credssp->server) { /* server echos the public key +1 */ - public_key2[0]--; + ap_integer_decrement_le(public_key2, public_key_length); } if (memcmp(public_key1, public_key2, public_key_length) != 0) @@ -705,8 +750,6 @@ SECURITY_STATUS credssp_decrypt_public_key_echo(rdpCredssp* credssp) return SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */ } - public_key2[0]++; - free(buffer); return SEC_E_OK; diff --git a/libfreerdp-crypto/tls.c b/libfreerdp-crypto/tls.c index 1bd2f9acb..f0d607a8b 100644 --- a/libfreerdp-crypto/tls.c +++ b/libfreerdp-crypto/tls.c @@ -467,7 +467,7 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) if (common_name) { xfree(common_name); - common_name=NULL ; + common_name = NULL; } verification_status = true; /* success! */ @@ -508,7 +508,7 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) if (!accept_certificate) { /* user did not accept, abort and do not add entry in known_hosts file */ - verification_status = false; /* failure! */ + verification_status = false; /* failure! */ } else { @@ -533,20 +533,6 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) xfree(fingerprint); } -#ifndef _WIN32 - if (common_name) - xfree(common_name); - - if (alt_names) - { - for (index = 0; index < alt_names_count; index++) - xfree(alt_names[index]); - - xfree(alt_names); - xfree(alt_names_lengths) ; - } -#endif - if (certificate_data) { xfree(certificate_data->fingerprint);