summaryrefslogtreecommitdiff
path: root/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r--src/openvpn/ssl_openssl.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index e57b6d2..a78dae9 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -423,6 +423,62 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
}
void
+convert_tls13_list_to_openssl(char *openssl_ciphers, size_t len,
+ const char *ciphers)
+{
+ /*
+ * OpenSSL (and official IANA) cipher names have _ in them. We
+ * historically used names with - in them. Silently convert names
+ * with - to names with _ to support both
+ */
+ if (strlen(ciphers) >= (len - 1))
+ {
+ msg(M_FATAL,
+ "Failed to set restricted TLS 1.3 cipher list, too long (>%d).",
+ (int) (len - 1));
+ }
+
+ strncpy(openssl_ciphers, ciphers, len);
+
+ for (size_t i = 0; i < strlen(openssl_ciphers); i++)
+ {
+ if (openssl_ciphers[i] == '-')
+ {
+ openssl_ciphers[i] = '_';
+ }
+ }
+}
+
+void
+tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers)
+{
+ if (ciphers == NULL)
+ {
+ /* default cipher list of OpenSSL 1.1.1 is sane, do not set own
+ * default as we do with tls-cipher */
+ return;
+ }
+
+#if (OPENSSL_VERSION_NUMBER < 0x1010100fL)
+ crypto_msg(M_WARN, "Not compiled with OpenSSL 1.1.1 or higher. "
+ "Ignoring TLS 1.3 only tls-ciphersuites '%s' setting.",
+ ciphers);
+#else
+ ASSERT(NULL != ctx);
+
+ char openssl_ciphers[4096];
+ convert_tls13_list_to_openssl(openssl_ciphers, sizeof(openssl_ciphers),
+ ciphers);
+
+ if (!SSL_CTX_set_ciphersuites(ctx->ctx, openssl_ciphers))
+ {
+ crypto_msg(M_FATAL, "Failed to set restricted TLS 1.3 cipher list: %s",
+ openssl_ciphers);
+ }
+#endif
+}
+
+void
tls_ctx_set_cert_profile(struct tls_root_ctx *ctx, const char *profile)
{
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
@@ -627,7 +683,7 @@ tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name
EC_KEY_free(ecdh);
#else /* ifndef OPENSSL_NO_EC */
- msg(M_DEBUG, "Your OpenSSL library was built without elliptic curve support."
+ msg(D_LOW, "Your OpenSSL library was built without elliptic curve support."
" Skipping ECDH parameter loading.");
#endif /* OPENSSL_NO_EC */
}
@@ -1778,14 +1834,11 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix)
}
void
-show_available_tls_ciphers(const char *cipher_list,
- const char *tls_cert_profile)
+show_available_tls_ciphers_list(const char *cipher_list,
+ const char *tls_cert_profile,
+ const bool tls13)
{
struct tls_root_ctx tls_ctx;
- SSL *ssl;
- const char *cipher_name;
- const tls_cipher_name_pair *pair;
- int priority = 0;
tls_ctx.ctx = SSL_CTX_new(SSLv23_method());
if (!tls_ctx.ctx)
@@ -1793,34 +1846,59 @@ show_available_tls_ciphers(const char *cipher_list,
crypto_msg(M_FATAL, "Cannot create SSL_CTX object");
}
- ssl = SSL_new(tls_ctx.ctx);
- if (!ssl)
+#if (OPENSSL_VERSION_NUMBER >= 0x1010100fL)
+ if (tls13)
{
- crypto_msg(M_FATAL, "Cannot create SSL object");
+ SSL_CTX_set_min_proto_version(tls_ctx.ctx, TLS1_3_VERSION);
+ tls_ctx_restrict_ciphers_tls13(&tls_ctx, cipher_list);
+ }
+ else
+#endif
+ {
+ SSL_CTX_set_max_proto_version(tls_ctx.ctx, TLS1_2_VERSION);
+ tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
}
tls_ctx_set_cert_profile(&tls_ctx, tls_cert_profile);
- 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++)))
+ SSL *ssl = SSL_new(tls_ctx.ctx);
+ if (!ssl)
{
- pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+ crypto_msg(M_FATAL, "Cannot create SSL object");
+ }
+
+#if (OPENSSL_VERSION_NUMBER < 0x1010000fL)
+ STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl);
+#else
+ STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl);
+#endif
+ for (int i=0;i < sk_SSL_CIPHER_num(sk);i++)
+ {
+ const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
+
+ const char *cipher_name = SSL_CIPHER_get_name(c);
- if (NULL == pair)
+ const tls_cipher_name_pair *pair =
+ tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+
+ if (tls13)
+ {
+ printf("%s\n", cipher_name);
+ }
+ else if (NULL == pair)
{
/* No translation found, print warning */
- printf("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", cipher_name);
+ printf("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n",
+ cipher_name);
}
else
{
printf("%s\n", pair->iana_name);
}
-
}
- printf("\n" SHOW_TLS_CIPHER_LIST_WARNING);
-
+#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
+ sk_SSL_CIPHER_free(sk);
+#endif
SSL_free(ssl);
SSL_CTX_free(tls_ctx.ctx);
}