diff options
Diffstat (limited to 'openvpn/src/openvpn/ssl_openssl.c')
-rw-r--r-- | openvpn/src/openvpn/ssl_openssl.c | 171 |
1 files changed, 89 insertions, 82 deletions
diff --git a/openvpn/src/openvpn/ssl_openssl.c b/openvpn/src/openvpn/ssl_openssl.c index f41bb711..9dced724 100644 --- a/openvpn/src/openvpn/ssl_openssl.c +++ b/openvpn/src/openvpn/ssl_openssl.c @@ -93,22 +93,6 @@ tls_clear_error() ERR_clear_error (); } -/* - * OpenSSL callback to get a temporary RSA key, mostly - * used for export ciphers. - */ -static RSA * -tmp_rsa_cb (SSL * s, int is_export, int keylength) -{ - static RSA *rsa_tmp = NULL; - if (rsa_tmp == NULL) - { - msg (D_HANDSHAKE, "Generating temp (%d bit) RSA key", keylength); - rsa_tmp = RSA_generate_key (keylength, RSA_F4, NULL, NULL); - } - return (rsa_tmp); -} - void tls_ctx_server_new(struct tls_root_ctx *ctx) { @@ -117,9 +101,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx) ctx->ctx = SSL_CTX_new (SSLv23_server_method ()); if (ctx->ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new TLSv1_server_method"); - - SSL_CTX_set_tmp_rsa_callback (ctx->ctx, tmp_rsa_cb); + msg (M_SSLERR, "SSL_CTX_new SSLv23_server_method"); } void @@ -130,7 +112,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx) ctx->ctx = SSL_CTX_new (SSLv23_client_method ()); if (ctx->ctx == NULL) - msg (M_SSLERR, "SSL_CTX_new TLSv1_client_method"); + msg (M_SSLERR, "SSL_CTX_new SSLv23_client_method"); } void @@ -235,71 +217,93 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) { - size_t begin_of_cipher, end_of_cipher; - - const char *current_cipher; - size_t current_cipher_len; + if (ciphers == NULL) + { + /* Use sane default */ + if(!SSL_CTX_set_cipher_list(ctx->ctx, "DEFAULT:!EXP")) + msg(M_SSLERR, "Failed to set default TLS cipher list."); + return; + } + else + { + /* Parse supplied cipher list and pass on to OpenSSL */ + size_t begin_of_cipher, end_of_cipher; - const tls_cipher_name_pair *cipher_pair; + const char *current_cipher; + size_t current_cipher_len; - char openssl_ciphers[4096]; - size_t openssl_ciphers_len = 0; - openssl_ciphers[0] = '\0'; + const tls_cipher_name_pair *cipher_pair; - ASSERT(NULL != ctx); + char openssl_ciphers[4096]; + size_t openssl_ciphers_len = 0; + openssl_ciphers[0] = '\0'; - // Translate IANA cipher suite names to OpenSSL names - begin_of_cipher = end_of_cipher = 0; - for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) { - end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":"); - cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher); + ASSERT(NULL != ctx); - if (NULL == cipher_pair) + // Translate IANA cipher suite names to OpenSSL names + begin_of_cipher = end_of_cipher = 0; + for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) { - // No translation found, use original - current_cipher = &ciphers[begin_of_cipher]; - current_cipher_len = end_of_cipher - begin_of_cipher; - - // Issue warning on missing translation - // %.*s format specifier expects length of type int, so guarantee - // that length is small enough and cast to int. - msg (M_WARN, "No valid translation found for TLS cipher '%.*s'", - constrain_int(current_cipher_len, 0, 256), current_cipher); - } - else - { - // Use OpenSSL name - current_cipher = cipher_pair->openssl_name; - current_cipher_len = strlen(current_cipher); + end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":"); + cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], + end_of_cipher - begin_of_cipher); - if (end_of_cipher - begin_of_cipher == current_cipher_len && - 0 == memcmp (&ciphers[begin_of_cipher], cipher_pair->openssl_name, end_of_cipher - begin_of_cipher)) - { - // Non-IANA name used, show warning - msg (M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name); - } - } - - // Make sure new cipher name fits in cipher string - if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len) { - msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%d).", (int)sizeof(openssl_ciphers)-1); - } - - // Concatenate cipher name to OpenSSL cipher string - memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len); - openssl_ciphers_len += current_cipher_len; - openssl_ciphers[openssl_ciphers_len] = ':'; - openssl_ciphers_len++; + if (NULL == cipher_pair) + { + // No translation found, use original + current_cipher = &ciphers[begin_of_cipher]; + current_cipher_len = end_of_cipher - begin_of_cipher; + + // Issue warning on missing translation + // %.*s format specifier expects length of type int, so guarantee + // that length is small enough and cast to int. + msg (M_WARN, "No valid translation found for TLS cipher '%.*s'", + constrain_int(current_cipher_len, 0, 256), current_cipher); + } + else + { + // Use OpenSSL name + current_cipher = cipher_pair->openssl_name; + current_cipher_len = strlen(current_cipher); + + if (end_of_cipher - begin_of_cipher == current_cipher_len && + 0 == memcmp (&ciphers[begin_of_cipher], + cipher_pair->openssl_name, + end_of_cipher - begin_of_cipher)) + { + // Non-IANA name used, show warning + msg (M_WARN, "Deprecated TLS cipher name '%s', " + "please use IANA name '%s'", cipher_pair->openssl_name, + cipher_pair->iana_name); + } + } - end_of_cipher++; - } + // Make sure new cipher name fits in cipher string + if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < + current_cipher_len) { + msg(M_SSLERR, + "Failed to set restricted TLS cipher list, too long (>%d).", + (int)sizeof(openssl_ciphers)-1); + } + + // Concatenate cipher name to OpenSSL cipher string + memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, + current_cipher_len); + openssl_ciphers_len += current_cipher_len; + openssl_ciphers[openssl_ciphers_len] = ':'; + openssl_ciphers_len++; + + end_of_cipher++; + } - if (openssl_ciphers_len > 0) - openssl_ciphers[openssl_ciphers_len-1] = '\0'; + if (openssl_ciphers_len > 0) + openssl_ciphers[openssl_ciphers_len-1] = '\0'; - // Set OpenSSL cipher list - if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers)) - msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", openssl_ciphers); + // Set OpenSSL cipher list + if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers)) + msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", + openssl_ciphers); + } } void @@ -1274,22 +1278,25 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix) } void -show_available_tls_ciphers () +show_available_tls_ciphers (const char *cipher_list) { - SSL_CTX *ctx; + struct tls_root_ctx tls_ctx; SSL *ssl; const char *cipher_name; const tls_cipher_name_pair *pair; int priority = 0; - ctx = SSL_CTX_new (TLSv1_method ()); - if (!ctx) + tls_ctx.ctx = SSL_CTX_new (SSLv23_method ()); + if (!tls_ctx.ctx) msg (M_SSLERR, "Cannot create SSL_CTX object"); - ssl = SSL_new (ctx); + ssl = SSL_new (tls_ctx.ctx); if (!ssl) msg (M_SSLERR, "Cannot create SSL object"); + if (cipher_list) + tls_ctx_restrict_ciphers(&tls_ctx, cipher_list); + printf ("Available TLS Ciphers,\n"); printf ("listed in order of preference:\n\n"); while ((cipher_name = SSL_get_cipher_list (ssl, priority++))) @@ -1307,7 +1314,7 @@ show_available_tls_ciphers () printf ("\n"); SSL_free (ssl); - SSL_CTX_free (ctx); + SSL_CTX_free (tls_ctx.ctx); } void @@ -1317,7 +1324,7 @@ get_highest_preference_tls_cipher (char *buf, int size) SSL *ssl; const char *cipher_name; - ctx = SSL_CTX_new (TLSv1_method ()); + ctx = SSL_CTX_new (SSLv23_method ()); if (!ctx) msg (M_SSLERR, "Cannot create SSL_CTX object"); ssl = SSL_new (ctx); |