summaryrefslogtreecommitdiff
path: root/openvpn/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn/src/openvpn/ssl_openssl.c')
-rw-r--r--openvpn/src/openvpn/ssl_openssl.c171
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);