From bd6760bd136b85a2c44ef0145a3d9dac4a688f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 11 Oct 2013 06:12:50 -0400 Subject: [PATCH] libfreerdp-core: start implement TSG OpenSSL BIO --- include/freerdp/crypto/tls.h | 3 + libfreerdp/core/transport.c | 104 +++++++++++++++++++++++++++++++++++ libfreerdp/core/transport.h | 1 + libfreerdp/crypto/tls.c | 27 +++++++-- 4 files changed, 130 insertions(+), 5 deletions(-) diff --git a/include/freerdp/crypto/tls.h b/include/freerdp/crypto/tls.h index 7e9aca995..a18597308 100644 --- a/include/freerdp/crypto/tls.h +++ b/include/freerdp/crypto/tls.h @@ -39,9 +39,12 @@ typedef struct rdp_tls rdpTls; struct rdp_tls { SSL* ssl; + BIO* bio; + void* tsg; int sockfd; SSL_CTX* ctx; BYTE* PublicKey; + BIO_METHOD* methods; DWORD PublicKeyLength; rdpSettings* settings; SecPkgContext_Bindings* Bindings; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index e06e92893..fb3c013d8 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -104,10 +104,114 @@ BOOL transport_connect_rdp(rdpTransport* transport) return TRUE; } +static int transport_bio_tsg_write(BIO* bio, const char* buf, int num) +{ + printf("transport_bio_tsg_write: %d\n", num); + + tsg_write((rdpTsg*) bio->ptr, (BYTE*) buf, num); + BIO_clear_retry_flags(bio); + + return num; +} + +static int transport_bio_tsg_read(BIO* bio, char* buf, int size) +{ + printf("transport_bio_tsg_read: %d\n", size); + + BIO_clear_retry_flags(bio); + + return 1; +} + +static int transport_bio_tsg_puts(BIO* bio, const char* str) +{ + printf("transport_bio_tsg_puts: %d\n", strlen(str)); + return 1; +} + +static int transport_bio_tsg_gets(BIO* bio, char* str, int size) +{ + printf("transport_bio_tsg_gets: %d\n", size); + return 1; +} + +static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2) +{ + printf("transport_bio_tsg_puts: cmd: %d arg1: %d arg2: %p\n", cmd, arg1, arg2); + return 1; +} + +static int transport_bio_tsg_new(BIO* bio) +{ + printf("transport_bio_tsg_new\n"); + + bio->init = 1; + bio->num = 0; + bio->ptr = NULL; + bio->flags = 0; + + return 1; +} + +static int transport_bio_tsg_free(BIO* bio) +{ + printf("transport_bio_tsg_free\n"); + return 1; +} + +#define BIO_TYPE_TSG 65 + +static BIO_METHOD transport_bio_tsg_methods = +{ + BIO_TYPE_TSG, + "TSGateway", + transport_bio_tsg_write, + transport_bio_tsg_read, + transport_bio_tsg_puts, + transport_bio_tsg_gets, + transport_bio_tsg_ctrl, + transport_bio_tsg_new, + transport_bio_tsg_free, + NULL, +}; + +BIO_METHOD* BIO_s_tsg(void) +{ + return &transport_bio_tsg_methods; +} + BOOL transport_connect_tls(rdpTransport* transport) { if (transport->layer == TRANSPORT_LAYER_TSG) + { + if (!transport->TlsIn) + transport->TlsIn = tls_new(transport->settings); + + if (!transport->TlsOut) + transport->TlsOut = transport->TlsIn; + + transport->TlsIn->methods = BIO_s_tsg(); + transport->TlsIn->tsg = (void*) transport->tsg; + + transport->layer = TRANSPORT_LAYER_TLS; + + if (tls_connect(transport->TlsIn) != TRUE) + { + if (!connectErrorCode) + connectErrorCode = TLSCONNECTERROR; + + tls_free(transport->TlsIn); + + if (transport->TlsIn == transport->TlsOut) + transport->TlsIn = transport->TlsOut = NULL; + else + transport->TlsIn = NULL; + + return FALSE; + } + return TRUE; + } if (transport->TlsIn == NULL) transport->TlsIn = tls_new(transport->settings); diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index bb573b6eb..821ab37fd 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -25,6 +25,7 @@ typedef enum TRANSPORT_LAYER_TCP, TRANSPORT_LAYER_TLS, TRANSPORT_LAYER_TSG, + TRANSPORT_LAYER_TSG_TLS, TRANSPORT_LAYER_CLOSED } TRANSPORT_LAYER; diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 3e089e418..7b58645b6 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -106,7 +106,7 @@ BOOL tls_connect(rdpTls* tls) tls->ctx = SSL_CTX_new(TLSv1_client_method()); - if (tls->ctx == NULL) + if (!tls->ctx) { fprintf(stderr, "SSL_CTX_new failed\n"); return FALSE; @@ -147,16 +147,33 @@ BOOL tls_connect(rdpTls* tls) tls->ssl = SSL_new(tls->ctx); - if (tls->ssl == NULL) + if (!tls->ssl) { fprintf(stderr, "SSL_new failed\n"); return FALSE; } - if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) + if (tls->tsg) { - fprintf(stderr, "SSL_set_fd failed\n"); - return FALSE; + tls->bio = BIO_new(tls->methods); + + if (!tls->bio) + { + fprintf(stderr, "BIO_new failed\n"); + return FALSE; + } + + tls->bio->ptr = tls->tsg; + + SSL_set_bio(tls->ssl, tls->bio, tls->bio); + } + else + { + if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) + { + fprintf(stderr, "SSL_set_fd failed\n"); + return FALSE; + } } connection_status = SSL_connect(tls->ssl);