|
|
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 |
|