Ticket #1118: 0001-Add-support-for-tls-ciphersuites-for-TLS-1.3.patch
File 0001-Add-support-for-tls-ciphersuites-for-TLS-1.3.patch, 14.2 KB (added by , 6 years ago) |
---|
-
doc/openvpn.8
From 6f427399727264be4b0938c081f72c96c2108d41 Mon Sep 17 00:00:00 2001 From: Arne Schwabe <arne@rfc2549.org> Date: Wed, 26 Sep 2018 15:10:28 +0200 Subject: [PATCH] Add support for tls-ciphersuites for TLS 1.3 OpenSSL 1.1.1 introduces a seperate list for TLS 1.3 ciphers. As these interfaces are meant to be user facing or not exposed at all and we expose the tls-cipher interface, we should also expose tls-cipherlist. Combining both settings into tls-cipher would add a lot of glue logic that needs to be maintained and is error prone. On top of that, users should not set either settings unless absolutely required. OpenSSL's own s_client/s_server also expose both settings and I believe most other software will too: -cipher val Specify TLSv1.2 and below cipher list to be used -ciphersuites val Specify TLSv1.3 ciphersuites to be used For mbed TLS only the future can tell if we will see a combined or also two seperate lists. --- doc/openvpn.8 | 19 ++++- src/openvpn/options.c | 7 ++ src/openvpn/options.h | 1 + src/openvpn/ssl.c | 3 +- src/openvpn/ssl_backend.h | 13 ++- src/openvpn/ssl_mbedtls.c | 12 +++ src/openvpn/ssl_openssl.c | 165 ++++++++++++++++++++++---------------- 7 files changed, 149 insertions(+), 71 deletions(-) diff --git a/doc/openvpn.8 b/doc/openvpn.8 index 15a10296..0b44a29d 100644
a b determines the derivation of the tunnel session keys. 5001 5001 .\"********************************************************* 5002 5002 .TP 5003 5003 .B \-\-tls\-cipher l 5004 .TQ 5005 .B \-\-tls\-ciphersuites l 5004 5006 A list 5005 5007 .B l 5006 5008 of allowable TLS ciphers delimited by a colon (":"). 5007 5009 5008 Th issetting can be used to ensure that certain cipher suites are used (or5010 These setting can be used to ensure that certain cipher suites are used (or 5009 5011 not used) for the TLS connection. OpenVPN uses TLS to secure the control 5010 5012 channel, over which the keys that are used to protect the actual VPN traffic 5011 5013 are exchanged. … … The supplied list of ciphers is (after potential OpenSSL/IANA name translation) 5014 5016 simply supplied to the crypto library. Please see the OpenSSL and/or mbed TLS 5015 5017 documentation for details on the cipher list interpretation. 5016 5018 5019 For OpenSSL the 5020 .B \-\-tls-cipher 5021 is used for TLS 1.2 and below. For TLS 1.3 and up 5022 the 5023 .B \-\-tls\-ciphersuites 5024 setting is used. mbed TLS has no TLS 1.3 support yet and only the 5025 .B \-\-tls-cipher 5026 setting is used. 5027 5017 5028 Use 5018 5029 .B \-\-show\-tls 5019 5030 to see a list of TLS ciphers supported by your crypto library. 5020 5031 5021 5032 Warning! 5022 5033 .B \-\-tls\-cipher 5023 is an expert feature, which \- if used correcly \- can improve the security of 5034 and 5035 .B \-\-tls\-ciphersuites 5036 are expert features, which \- if used correcly \- can improve the security of 5024 5037 your VPN connection. But it is also easy to unwittingly use it to carefully 5025 5038 align a gun with your foot, or just break your connection. Use with care! 5026 5039 … … The default for \-\-tls\-cipher is to use mbed TLS's default cipher list 5028 5041 when using mbed TLS or 5029 5042 "DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:!SRP:!kRSA" when using 5030 5043 OpenSSL. 5044 5045 The default for \-\-tls\-ciphersuites is to use the crypto library's default. 5031 5046 .\"********************************************************* 5032 5047 .TP 5033 5048 .B \-\-tls\-cert\-profile profile -
src/openvpn/options.c
diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 03550c1e..a574c9f9 100644
a b show_settings(const struct options *o) 1766 1766 #endif 1767 1767 SHOW_STR(cipher_list); 1768 1768 SHOW_STR(tls_cert_profile); 1769 SHOW_STR(cipher_list_tls13); 1769 1770 SHOW_STR(tls_verify); 1770 1771 SHOW_STR(tls_export_cert); 1771 1772 SHOW_INT(verify_x509_type); … … options_postprocess_verify_ce(const struct options *options, const struct connec 2759 2760 MUST_BE_UNDEF(pkcs12_file); 2760 2761 #endif 2761 2762 MUST_BE_UNDEF(cipher_list); 2763 MUST_BE_UNDEF(cipher_list_tls13); 2762 2764 MUST_BE_UNDEF(tls_cert_profile); 2763 2765 MUST_BE_UNDEF(tls_verify); 2764 2766 MUST_BE_UNDEF(tls_export_cert); … … add_option(struct options *options, 7948 7950 VERIFY_PERMISSION(OPT_P_GENERAL); 7949 7951 options->tls_cert_profile = p[1]; 7950 7952 } 7953 else if (streq(p[0], "tls-ciphersuites") && p[1] && !p[2]) 7954 { 7955 VERIFY_PERMISSION(OPT_P_GENERAL); 7956 options->cipher_list_tls13 = p[1]; 7957 } 7951 7958 else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) 7952 7959 || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) 7953 7960 { -
src/openvpn/options.h
diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 4c3bc4fb..3e7ef4f8 100644
a b struct options 508 508 const char *priv_key_file; 509 509 const char *pkcs12_file; 510 510 const char *cipher_list; 511 const char *cipher_list_tls13; 511 512 const char *tls_cert_profile; 512 513 const char *ecdh_curve; 513 514 const char *tls_verify; -
src/openvpn/ssl.c
diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index e5e4aac2..616c2696 100644
a b init_ssl(const struct options *options, struct tls_root_ctx *new_ctx) 626 626 tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile); 627 627 628 628 /* Allowable ciphers */ 629 /* Since @SECLEVEL also influ ces loading of certificates, set the629 /* Since @SECLEVEL also influences loading of certificates, set the 630 630 * cipher restrictions before loading certificates */ 631 631 tls_ctx_restrict_ciphers(new_ctx, options->cipher_list); 632 tls_ctx_restrict_ciphers_tls13(new_ctx, options->cipher_list_tls13); 632 633 633 634 if (!tls_ctx_set_options(new_ctx, options->ssl_flags)) 634 635 { -
src/openvpn/ssl_backend.h
diff --git a/src/openvpn/ssl_backend.h b/src/openvpn/ssl_backend.h index 5023c02a..0995bb4c 100644
a b bool tls_ctx_initialised(struct tls_root_ctx *ctx); 169 169 bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); 170 170 171 171 /** 172 * Restrict the list of ciphers that can be used within the TLS context. 172 * Restrict the list of ciphers that can be used within the TLS context for TLS 1.2 173 * and below 173 174 * 174 175 * @param ctx TLS context to restrict, must be valid. 175 176 * @param ciphers String containing : delimited cipher names, or NULL to use … … bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags); 177 178 */ 178 179 void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers); 179 180 181 /** 182 * Restrict the list of ciphers that can be used within the TLS context for TLS 1.3 183 * and higher 184 * 185 * @param ctx TLS context to restrict, must be valid. 186 * @param ciphers String containing : delimited cipher names, or NULL to use 187 * sane defaults. 188 */ 189 void tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers); 190 180 191 /** 181 192 * Set the TLS certificate profile. The profile defines which crypto 182 193 * algorithms may be used in the supplied certificate. -
src/openvpn/ssl_mbedtls.c
diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c index e4850cb6..c9cc2aee 100644
a b tls_translate_cipher_name(const char *cipher_name) 222 222 return pair->iana_name; 223 223 } 224 224 225 void 226 tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers) 227 { 228 if (ciphers == NULL) 229 { 230 /* Nothing to do, return without warning message */ 231 return; 232 } 233 234 crypto_msg(M_WARN, "mbed TLS does not support setting tls-ciphersuites. Ignoring TLS 1.3 cipher list: %s", cipher); 235 } 236 225 237 void 226 238 tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) 227 239 { -
src/openvpn/ssl_openssl.c
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c index 51bb6843..ebb44f8b 100644
a b tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags) 322 322 return true; 323 323 } 324 324 325 void 326 convert_tls_list_to_openssl(char* openssl_ciphers, size_t len,const char *ciphers) 327 { 328 /* Parse supplied cipher list and pass on to OpenSSL */ 329 size_t begin_of_cipher, end_of_cipher; 330 331 const char *current_cipher; 332 size_t current_cipher_len; 333 334 const tls_cipher_name_pair *cipher_pair; 335 336 size_t openssl_ciphers_len = 0; 337 openssl_ciphers[0] = '\0'; 338 339 /* Translate IANA cipher suite names to OpenSSL names */ 340 begin_of_cipher = end_of_cipher = 0; 341 for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) 342 { 343 end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":"); 344 cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher); 345 346 if (NULL == cipher_pair) 347 { 348 /* No translation found, use original */ 349 current_cipher = &ciphers[begin_of_cipher]; 350 current_cipher_len = end_of_cipher - begin_of_cipher; 351 352 /* Issue warning on missing translation */ 353 /* %.*s format specifier expects length of type int, so guarantee */ 354 /* that length is small enough and cast to int. */ 355 msg(D_LOW, "No valid translation found for TLS cipher '%.*s'", 356 constrain_int(current_cipher_len, 0, 256), current_cipher); 357 } 358 else 359 { 360 /* Use OpenSSL name */ 361 current_cipher = cipher_pair->openssl_name; 362 current_cipher_len = strlen(current_cipher); 363 364 if (end_of_cipher - begin_of_cipher == current_cipher_len 365 && 0 != memcmp(&ciphers[begin_of_cipher], cipher_pair->iana_name, 366 end_of_cipher - begin_of_cipher)) 367 { 368 /* Non-IANA name used, show warning */ 369 msg(M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name); 370 } 371 } 372 373 /* Make sure new cipher name fits in cipher string */ 374 if ((SIZE_MAX - openssl_ciphers_len) < current_cipher_len 375 || (len - 1) < (openssl_ciphers_len + current_cipher_len)) 376 { 377 msg(M_FATAL, 378 "Failed to set restricted TLS cipher list, too long (>%d).", 379 (int)(len - 1)); 380 } 381 382 /* Concatenate cipher name to OpenSSL cipher string */ 383 memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len); 384 openssl_ciphers_len += current_cipher_len; 385 openssl_ciphers[openssl_ciphers_len] = ':'; 386 openssl_ciphers_len++; 387 388 end_of_cipher++; 389 } 390 391 if (openssl_ciphers_len > 0) 392 { 393 openssl_ciphers[openssl_ciphers_len-1] = '\0'; 394 } 395 } 396 397 void 398 tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers) 399 { 400 if (ciphers == NULL) 401 { 402 /* default cipher list of OpenSSL 1.1.1 is sane, do not set own own 403 * default as we do with tls-cipher */ 404 return; 405 } 406 407 char openssl_ciphers[4096]; 408 convert_tls_list_to_openssl(openssl_ciphers, sizeof(openssl_ciphers), ciphers); 409 410 #if (OPENSSL_VERSION_NUMBER < 0x1010100fL) 411 crypto_msg(M_WARN, "Not compiled with OpenSSL 1.1.1 or higher. Ignoring TLS 1.3 cipher list: %s", openssl_ciphers); 412 #else 413 ASSERT(NULL != ctx); 414 415 if (!SSL_CTX_set_ciphersuites(ctx->ctx, openssl_ciphers)) 416 { 417 crypto_msg(M_FATAL, "Failed to set restricted TLS 1.3 cipher list: %s", openssl_ciphers); 418 } 419 #endif 420 } 421 325 422 void 326 423 tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) 327 424 { … … tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) 345 442 return; 346 443 } 347 444 348 /* Parse supplied cipher list and pass on to OpenSSL */349 size_t begin_of_cipher, end_of_cipher;350 351 const char *current_cipher;352 size_t current_cipher_len;353 354 const tls_cipher_name_pair *cipher_pair;355 356 445 char openssl_ciphers[4096]; 357 size_t openssl_ciphers_len = 0; 358 openssl_ciphers[0] = '\0'; 446 convert_tls_list_to_openssl(openssl_ciphers, sizeof(openssl_ciphers), ciphers); 359 447 360 448 ASSERT(NULL != ctx); 361 449 362 /* Translate IANA cipher suite names to OpenSSL names */363 begin_of_cipher = end_of_cipher = 0;364 for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher)365 {366 end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");367 cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher);368 369 if (NULL == cipher_pair)370 {371 /* No translation found, use original */372 current_cipher = &ciphers[begin_of_cipher];373 current_cipher_len = end_of_cipher - begin_of_cipher;374 375 /* Issue warning on missing translation */376 /* %.*s format specifier expects length of type int, so guarantee */377 /* that length is small enough and cast to int. */378 msg(D_LOW, "No valid translation found for TLS cipher '%.*s'",379 constrain_int(current_cipher_len, 0, 256), current_cipher);380 }381 else382 {383 /* Use OpenSSL name */384 current_cipher = cipher_pair->openssl_name;385 current_cipher_len = strlen(current_cipher);386 387 if (end_of_cipher - begin_of_cipher == current_cipher_len388 && 0 != memcmp(&ciphers[begin_of_cipher], cipher_pair->iana_name,389 end_of_cipher - begin_of_cipher))390 {391 /* Non-IANA name used, show warning */392 msg(M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);393 }394 }395 396 /* Make sure new cipher name fits in cipher string */397 if ((SIZE_MAX - openssl_ciphers_len) < current_cipher_len398 || ((sizeof(openssl_ciphers)-1) < openssl_ciphers_len + current_cipher_len))399 {400 msg(M_FATAL,401 "Failed to set restricted TLS cipher list, too long (>%d).",402 (int)sizeof(openssl_ciphers)-1);403 }404 405 /* Concatenate cipher name to OpenSSL cipher string */406 memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len);407 openssl_ciphers_len += current_cipher_len;408 openssl_ciphers[openssl_ciphers_len] = ':';409 openssl_ciphers_len++;410 411 end_of_cipher++;412 }413 414 if (openssl_ciphers_len > 0)415 {416 openssl_ciphers[openssl_ciphers_len-1] = '\0';417 }418 419 450 /* Set OpenSSL cipher list */ 420 451 if (!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers)) 421 452 {