/* Exported convenience functions */ int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, BIO **bio2_p, size_t writebuf2) { BIO *bio1 = NULL, *bio2 = NULL; long r; int ret = 0; bio1 = BIO_new(BIO_s_bio()); if (bio1 == NULL) goto err; bio2 = BIO_new(BIO_s_bio()); if (bio2 == NULL) goto err; if (writebuf1) { r = BIO_set_write_buf_size(bio1, writebuf1); if (!r) goto err; } if (writebuf2) { r = BIO_set_write_buf_size(bio2, writebuf2); if (!r) goto err; } r = BIO_make_bio_pair(bio1, bio2); if (!r) goto err; ret = 1; err: if (ret == 0) { if (bio1) { BIO_free(bio1); bio1 = NULL; } if (bio2) { BIO_free(bio2); bio2 = NULL; } } *bio1_p = bio1; *bio2_p = bio2; return ret; }
int schannel_openssl_client_init(SCHANNEL_OPENSSL* context) { int status; long options = 0; context->ctx = SSL_CTX_new(TLSv1_client_method()); if (!context->ctx) { WLog_ERR(TAG, "SSL_CTX_new failed"); return -1; } /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(context->ctx, options); context->ssl = SSL_new(context->ctx); if (!context->ssl) { WLog_ERR(TAG, "SSL_new failed"); return -1; } context->bioRead = BIO_new(BIO_s_mem()); if (!context->bioRead) { WLog_ERR(TAG, "BIO_new failed"); return -1; } status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN); context->bioWrite = BIO_new(BIO_s_mem()); if (!context->bioWrite) { WLog_ERR(TAG, "BIO_new failed"); return -1; } status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN); status = BIO_make_bio_pair(context->bioRead, context->bioWrite); SSL_set_bio(context->ssl, context->bioRead, context->bioWrite); context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); return 0; }
int schannel_openssl_server_init(SCHANNEL_OPENSSL* context) { int status; long options = 0; context->ctx = SSL_CTX_new(SSLv23_server_method()); if (!context->ctx) { WLog_ERR(TAG, "SSL_CTX_new failed"); return -1; } /* * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(context->ctx, options); if (SSL_CTX_use_RSAPrivateKey_file(context->ctx, "/tmp/localhost.key", SSL_FILETYPE_PEM) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); goto out_rsa_key; } context->ssl = SSL_new(context->ctx); if (!context->ssl) { WLog_ERR(TAG, "SSL_new failed"); goto out_ssl_new; } if (SSL_use_certificate_file(context->ssl, "/tmp/localhost.crt", SSL_FILETYPE_PEM) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); goto out_use_certificate; } context->bioRead = BIO_new(BIO_s_mem()); if (!context->bioRead) { WLog_ERR(TAG, "BIO_new failed"); goto out_bio_read; } status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN); if (status != 1) { WLog_ERR(TAG, "BIO_set_write_buf_size failed for bioRead"); goto out_set_write_buf_read; } context->bioWrite = BIO_new(BIO_s_mem()); if (!context->bioWrite) { WLog_ERR(TAG, "BIO_new failed"); goto out_bio_write; } status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN); if (status != 1) { WLog_ERR(TAG, "BIO_set_write_buf_size failed for bioWrite"); goto out_set_write_buf_write; } status = BIO_make_bio_pair(context->bioRead, context->bioWrite); if (status != 1) { WLog_ERR(TAG, "BIO_make_bio_pair failed"); goto out_bio_pair; } SSL_set_bio(context->ssl, context->bioRead, context->bioWrite); context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); if (!context->ReadBuffer) { WLog_ERR(TAG, "Failed to allocate memory for ReadBuffer"); goto out_read_buffer; } context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); if (!context->WriteBuffer) { WLog_ERR(TAG, "Failed to allocate memory for WriteBuffer"); goto out_write_buffer; } return 0; out_write_buffer: free(context->ReadBuffer); out_read_buffer: out_bio_pair: out_set_write_buf_write: BIO_free_all(context->bioWrite); out_bio_write: out_set_write_buf_read: BIO_free_all(context->bioRead); out_bio_read: out_use_certificate: SSL_free(context->ssl); out_ssl_new: out_rsa_key: SSL_CTX_free(context->ctx); return -1; }