Blame SOURCES/libfreerdp-core-verify-TLS-certificate-with-both-TLS.patch

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