int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { RSA *rsa = RSA_private_key_from_bytes(der, der_len); if (rsa == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); return 0; } int ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); return ret; }
int SSL_use_RSAPrivateKey_file (SSL * ssl, const char *file, int type) { int j, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new (BIO_s_file_internal ()); if (in == NULL) { SSLerr (SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename (in, file) <= 0) { SSLerr (SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { j = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio (in, NULL); } else if (type == SSL_FILETYPE_PEM) { j = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey (in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { SSLerr (SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { SSLerr (SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); goto end; } ret = SSL_use_RSAPrivateKey (ssl, rsa); RSA_free (rsa); end: if (in != NULL) BIO_free (in); return (ret); }
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) { int ret; RSA *rsa; if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) { SSLerror(ssl, ERR_R_ASN1_LIB); return (0); } ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); return (ret); }
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len) { int ret; const unsigned char *p; RSA *rsa; p = d; if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); return (0); } ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); return (ret); }
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { int reason_code, ret = 0; BIO *in; RSA *rsa = NULL; in = BIO_new(BIO_s_file()); if (in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); goto end; } if (type == SSL_FILETYPE_ASN1) { reason_code = ERR_R_ASN1_LIB; rsa = d2i_RSAPrivateKey_bio(in, NULL); } else if (type == SSL_FILETYPE_PEM) { reason_code = ERR_R_PEM_LIB; rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, ssl->ctx->default_passwd_callback_userdata); } else { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); goto end; } if (rsa == NULL) { OPENSSL_PUT_ERROR(SSL, reason_code); goto end; } ret = SSL_use_RSAPrivateKey(ssl, rsa); RSA_free(rsa); end: BIO_free(in); return ret; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * 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; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #if defined(MICROSOFT_IOS_SNI_BUG) && !defined(OPENSSL_NO_TLSEXT) SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings* settings) { long options = 0; BIO* bio; RSA* rsa; X509* x509; /** * 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; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #ifndef OPENSSL_NO_TLSEXT /** * The Microsoft iOS clients eventually send a null or even double null * terminated hostname in the SNI TLS extension! * If the length indicator does not equal the hostname strlen OpenSSL * will abort (see openssl:ssl/t1_lib.c). * Here is a tcpdump segment of Microsoft Remote Desktop Client Version * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted * SNI hostname TLV blob when connection to server "abcd": * 00 name_type 0x00 (host_name) * 00 06 length_in_bytes 0x0006 * 61 62 63 64 00 00 host_name "abcd\0\0" * * Currently the only (runtime) workaround is setting an openssl tls * extension debug callback that sets the SSL context's servername_done * to 1 which effectively disables the parsing of that extension type. */ SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }