From 53fa7e1e996f23818e17ab59f1cb1849c533472d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 12 Feb 2012 12:46:53 -0500 Subject: [PATCH 1/5] libfreerdp-core: verify TLS certificate with both TLS and NLA --- libfreerdp-core/credssp.c | 44 ++++++++------------------------------------ libfreerdp-core/credssp.h | 1 - libfreerdp-core/nego.c | 5 ++++- libfreerdp-core/tls.c | 19 +++++++++++++++++++ libfreerdp-core/tls.h | 2 ++ libfreerdp-core/transport.c | 1 + 6 files changed, 34 insertions(+), 38 deletions(-) diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index e269a21..6ef40e1 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -119,33 +119,6 @@ int credssp_ntlmssp_init(rdpCredssp* credssp) } /** - * Get TLS public key. - * @param credssp - */ - -int credssp_get_public_key(rdpCredssp* credssp) -{ - int status; - CryptoCert cert; - - cert = tls_get_certificate(credssp->transport->tls); - - if (cert == NULL) - { - printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n"); - return 0; - } - - if (!tls_verify_certificate(credssp->transport->tls, cert, credssp->transport->settings->hostname)) - tls_disconnect(credssp->transport->tls); - - status = crypto_cert_get_public_key(cert, &credssp->public_key); - crypto_cert_free(cert); - - return status; -} - -/** * Authenticate with server using CredSSP. * @param credssp * @return 1 if authentication is successful @@ -160,9 +133,6 @@ int credssp_authenticate(rdpCredssp* credssp) if (credssp_ntlmssp_init(credssp) == 0) return 0; - if (credssp_get_public_key(credssp) == 0) - return 0; - /* NTLMSSP NEGOTIATE MESSAGE */ stream_attach(s, negoTokenBuffer, 2048); ntlmssp_send(ntlmssp, s); @@ -223,16 +193,18 @@ int credssp_authenticate(rdpCredssp* credssp) void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d) { uint8* p; + rdpTls* tls; uint8 signature[16]; rdpBlob encrypted_public_key; NTLMSSP *ntlmssp = credssp->ntlmssp; + tls = credssp->transport->tls; - freerdp_blob_alloc(d, credssp->public_key.length + 16); - ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature); + freerdp_blob_alloc(d, tls->public_key.length + 16); + ntlmssp_encrypt_message(ntlmssp, &tls->public_key, &encrypted_public_key, signature); #ifdef WITH_DEBUG_NLA - printf("Public Key (length = %d)\n", credssp->public_key.length); - freerdp_hexdump(credssp->public_key.data, credssp->public_key.length); + printf("Public Key (length = %d)\n", tls->public_key.length); + freerdp_hexdump(tls->public_key.data, tls->public_key.length); printf("\n"); printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length); @@ -264,6 +236,7 @@ int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d) uint8* signature; rdpBlob public_key; rdpBlob encrypted_public_key; + rdpTls* tls = credssp->transport->tls; signature = d->data; encrypted_public_key.data = (void*) (signature + 16); @@ -271,7 +244,7 @@ int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d) ntlmssp_decrypt_message(credssp->ntlmssp, &encrypted_public_key, &public_key, signature); - p1 = (uint8*) credssp->public_key.data; + p1 = (uint8*) tls->public_key.data; p2 = (uint8*) public_key.data; p2[0]--; @@ -661,7 +634,6 @@ void credssp_free(rdpCredssp* credssp) { if (credssp != NULL) { - freerdp_blob_free(&credssp->public_key); freerdp_blob_free(&credssp->ts_credentials); ntlmssp_free(credssp->ntlmssp); diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h index 3277425..d98554a 100644 --- a/libfreerdp-core/credssp.h +++ b/libfreerdp-core/credssp.h @@ -40,7 +40,6 @@ struct rdp_credssp rdpBlob pubKeyAuth; rdpBlob authInfo; int send_seq_num; - rdpBlob public_key; rdpBlob ts_credentials; rdpSettings* settings; CryptoRc4 rc4_seal_state; diff --git a/libfreerdp-core/nego.c b/libfreerdp-core/nego.c index 7eb810b..ab4da37 100644 --- a/libfreerdp-core/nego.c +++ b/libfreerdp-core/nego.c @@ -256,8 +256,10 @@ void nego_attempt_rdp(rdpNego* nego) boolean nego_recv_response(rdpNego* nego) { STREAM* s = transport_recv_stream_init(nego->transport, 1024); + if (transport_read(nego->transport, s) < 0) return false; + return nego_recv(nego->transport, s, nego->transport->recv_extra); } @@ -319,6 +321,7 @@ boolean nego_read_request(rdpNego* nego, STREAM* s) tpkt_read_header(s); li = tpdu_read_connection_request(s); + if (li != stream_get_left(s) + 6) { printf("Incorrect TPDU length indicator.\n"); @@ -403,7 +406,7 @@ boolean nego_send_negotiation_request(rdpNego* nego) { int cookie_length = strlen(nego->cookie); stream_write(s, "Cookie: mstshash=", 17); - stream_write(s, (uint8*)nego->cookie, cookie_length); + stream_write(s, (uint8*) nego->cookie, cookie_length); stream_write_uint8(s, 0x0D); /* CR */ stream_write_uint8(s, 0x0A); /* LF */ length += cookie_length + 19; diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c index 106f9ca..942b430 100644 --- a/libfreerdp-core/tls.c +++ b/libfreerdp-core/tls.c @@ -66,6 +66,23 @@ boolean tls_connect(rdpTls* tls) return false; } + tls->cert = tls_get_certificate(tls); + + if (tls->cert == NULL) + { + printf("tls_connect: tls_get_certificate failed to return the server certificate.\n"); + return false; + } + + if (!crypto_cert_get_public_key(tls->cert, &tls->public_key)) + { + printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); + return false; + } + + if (!tls_verify_certificate(tls, tls->cert, tls->settings->hostname)) + tls_disconnect(tls); + return true; } @@ -433,6 +450,8 @@ void tls_free(rdpTls* tls) if (tls->ctx) SSL_CTX_free(tls->ctx); + freerdp_blob_free(&tls->public_key); + certificate_store_free(tls->certificate_store); xfree(tls); diff --git a/libfreerdp-core/tls.h b/libfreerdp-core/tls.h index c3f2f59..e941dd0 100644 --- a/libfreerdp-core/tls.h +++ b/libfreerdp-core/tls.h @@ -36,6 +36,8 @@ struct rdp_tls SSL* ssl; int sockfd; SSL_CTX* ctx; + CryptoCert cert; + rdpBlob public_key; rdpSettings* settings; rdpCertificateStore* certificate_store; }; diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index df43a8e..f4c28d8 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -72,6 +72,7 @@ boolean transport_disconnect(rdpTransport* transport) { if (transport->layer == TRANSPORT_LAYER_TLS) tls_disconnect(transport->tls); + return tcp_disconnect(transport->tcp); } -- 2.5.5