|
|
24c59a |
From 3da7c6207ebc4002bc1b0260d7d7c581c2fd635e Mon Sep 17 00:00:00 2001
|
|
|
24c59a |
From: Chris <ccpp@gmx.at>
|
|
|
24c59a |
Date: Mon, 17 Jun 2013 21:19:01 +0200
|
|
|
24c59a |
Subject: [PATCH 3/5] 1) Add support for Wildcard Certificates 2) For Gateway
|
|
|
24c59a |
connections compare against gateway host name instead of target host
|
|
|
24c59a |
|
|
|
24c59a |
---
|
|
|
24c59a |
libfreerdp-core/tls.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-------
|
|
|
24c59a |
libfreerdp-core/tls.h | 1 +
|
|
|
24c59a |
2 files changed, 58 insertions(+), 9 deletions(-)
|
|
|
24c59a |
|
|
|
24c59a |
diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c
|
|
|
24c59a |
index b05100e..db09960 100644
|
|
|
24c59a |
--- a/libfreerdp-core/tls.c
|
|
|
24c59a |
+++ b/libfreerdp-core/tls.c
|
|
|
24c59a |
@@ -25,6 +25,7 @@
|
|
|
24c59a |
boolean tls_connect(rdpTls* tls)
|
|
|
24c59a |
{
|
|
|
24c59a |
int connection_status;
|
|
|
24c59a |
+ char *hostname;
|
|
|
24c59a |
|
|
|
24c59a |
tls->ctx = SSL_CTX_new(TLSv1_client_method());
|
|
|
24c59a |
|
|
|
24c59a |
@@ -80,7 +81,13 @@ boolean tls_connect(rdpTls* tls)
|
|
|
24c59a |
return false;
|
|
|
24c59a |
}
|
|
|
24c59a |
|
|
|
24c59a |
- if (!tls_verify_certificate(tls, tls->cert, tls->settings->hostname)) {
|
|
|
24c59a |
+ if (tls->settings->ts_gateway)
|
|
|
24c59a |
+ hostname = tls->settings->tsg_hostname;
|
|
|
24c59a |
+ else
|
|
|
24c59a |
+ hostname = tls->settings->hostname;
|
|
|
24c59a |
+
|
|
|
24c59a |
+ if (!tls_verify_certificate(tls, tls->cert, hostname))
|
|
|
24c59a |
+ {
|
|
|
24c59a |
printf("tls_connect: certificate not trusted, aborting.\n");
|
|
|
24c59a |
tls_disconnect(tls);
|
|
|
24c59a |
return false;
|
|
|
24c59a |
@@ -253,6 +260,50 @@ CryptoCert tls_get_certificate(rdpTls* tls)
|
|
|
24c59a |
return cert;
|
|
|
24c59a |
}
|
|
|
24c59a |
|
|
|
24c59a |
+boolean tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
|
|
24c59a |
+{
|
|
|
24c59a |
+ if (strlen(hostname) == pattern_length)
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ if (memcmp((void*) hostname, (void*) pattern, pattern_length) == 0)
|
|
|
24c59a |
+ return TRUE;
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+
|
|
|
24c59a |
+ /* ccpp: Check for wildcard certificates */
|
|
|
24c59a |
+ if (memchr(pattern, '*', pattern_length) != NULL)
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ /* The wildcard matches one subdomain level (all except a dot) */
|
|
|
24c59a |
+
|
|
|
24c59a |
+ int pattern_position = 0;
|
|
|
24c59a |
+ int hostname_position = 0;
|
|
|
24c59a |
+
|
|
|
24c59a |
+ for(; hostname[hostname_position] && pattern_position < pattern_length; pattern_position++, hostname_position++)
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ if( pattern[pattern_position] == '*' ) {
|
|
|
24c59a |
+ while( hostname[hostname_position] != '.' && hostname[hostname_position] != '\0' )
|
|
|
24c59a |
+ hostname_position++;
|
|
|
24c59a |
+
|
|
|
24c59a |
+ pattern_position++;
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+
|
|
|
24c59a |
+ if (hostname[hostname_position] != pattern[pattern_position] )
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ return FALSE;
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+
|
|
|
24c59a |
+ if (pattern_length > 2 && pattern[0] == '*' && pattern[1] == '.')
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ char *check_hostname = &hostname[ strlen(hostname) - pattern_length+1 ];
|
|
|
24c59a |
+ if (memcmp((void*) check_hostname, (void*) &pattern[1], pattern_length - 1) == 0 )
|
|
|
24c59a |
+ {
|
|
|
24c59a |
+ return TRUE;
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+ }
|
|
|
24c59a |
+
|
|
|
24c59a |
+ return FALSE;
|
|
|
24c59a |
+}
|
|
|
24c59a |
+
|
|
|
24c59a |
boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
|
|
24c59a |
{
|
|
|
24c59a |
int match;
|
|
|
24c59a |
@@ -288,11 +339,8 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
|
|
24c59a |
|
|
|
24c59a |
if (common_name != NULL)
|
|
|
24c59a |
{
|
|
|
24c59a |
- if (strlen(hostname) == common_name_length)
|
|
|
24c59a |
- {
|
|
|
24c59a |
- if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0)
|
|
|
24c59a |
- hostname_match = true;
|
|
|
24c59a |
- }
|
|
|
24c59a |
+ if (tls_match_hostname(common_name, common_name_length, hostname))
|
|
|
24c59a |
+ hostname_match = TRUE;
|
|
|
24c59a |
}
|
|
|
24c59a |
|
|
|
24c59a |
/* compare against alternative names */
|
|
|
24c59a |
@@ -301,10 +349,10 @@ boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
|
|
24c59a |
{
|
|
|
24c59a |
for (index = 0; index < alt_names_count; index++)
|
|
|
24c59a |
{
|
|
|
24c59a |
- if (strlen(hostname) == alt_names_lengths[index])
|
|
|
24c59a |
+ if (tls_match_hostname(alt_names[index], alt_names_lengths[index], hostname))
|
|
|
24c59a |
{
|
|
|
24c59a |
- if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0)
|
|
|
24c59a |
- hostname_match = true;
|
|
|
24c59a |
+ hostname_match = TRUE;
|
|
|
24c59a |
+ break;
|
|
|
24c59a |
}
|
|
|
24c59a |
}
|
|
|
24c59a |
}
|
|
|
24c59a |
diff --git a/libfreerdp-core/tls.h b/libfreerdp-core/tls.h
|
|
|
24c59a |
index e941dd0..b2218f9 100644
|
|
|
24c59a |
--- a/libfreerdp-core/tls.h
|
|
|
24c59a |
+++ b/libfreerdp-core/tls.h
|
|
|
24c59a |
@@ -50,6 +50,7 @@ int tls_read(rdpTls* tls, uint8* data, int length);
|
|
|
24c59a |
int tls_write(rdpTls* tls, uint8* data, int length);
|
|
|
24c59a |
|
|
|
24c59a |
CryptoCert tls_get_certificate(rdpTls* tls);
|
|
|
24c59a |
+boolean tls_match_hostname(char *pattern, int pattern_length, char *hostname);
|
|
|
24c59a |
boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
|
|
24c59a |
void tls_print_certificate_error(char* hostname, char* fingerprint);
|
|
|
24c59a |
void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count);
|
|
|
24c59a |
--
|
|
|
24c59a |
2.5.5
|
|
|
24c59a |
|