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 plaisthos, 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. 
    50015001.\"*********************************************************
    50025002.TP
    50035003.B \-\-tls\-cipher l
     5004.TQ
     5005.B \-\-tls\-ciphersuites l
    50045006A list
    50055007.B l
    50065008of allowable TLS ciphers delimited by a colon (":").
    50075009
    5008 This setting can be used to ensure that certain cipher suites are used (or
     5010These setting can be used to ensure that certain cipher suites are used (or
    50095011not used) for the TLS connection.  OpenVPN uses TLS to secure the control
    50105012channel, over which the keys that are used to protect the actual VPN traffic
    50115013are exchanged.
    The supplied list of ciphers is (after potential OpenSSL/IANA name translation) 
    50145016simply supplied to the crypto library.  Please see the OpenSSL and/or mbed TLS
    50155017documentation for details on the cipher list interpretation.
    50165018
     5019For OpenSSL the
     5020.B \-\-tls-cipher
     5021is used for TLS 1.2 and below. For TLS 1.3 and up
     5022the
     5023.B \-\-tls\-ciphersuites
     5024setting is used. mbed TLS has no TLS 1.3 support yet and only the
     5025.B \-\-tls-cipher
     5026setting is used.
     5027
    50175028Use
    50185029.B \-\-show\-tls
    50195030to see a list of TLS ciphers supported by your crypto library.
    50205031
    50215032Warning!
    50225033.B \-\-tls\-cipher
    5023 is an expert feature, which \- if used correcly \- can improve the security of
     5034and
     5035.B \-\-tls\-ciphersuites
     5036are expert features, which \- if used correcly \- can improve the security of
    50245037your VPN connection.  But it is also easy to unwittingly use it to carefully
    50255038align a gun with your foot, or just break your connection.  Use with care!
    50265039
    The default for \-\-tls\-cipher is to use mbed TLS's default cipher list 
    50285041when using mbed TLS or
    50295042"DEFAULT:!EXP:!LOW:!MEDIUM:!kDH:!kECDH:!DSS:!PSK:!SRP:!kRSA" when using
    50305043OpenSSL.
     5044
     5045The default for \-\-tls\-ciphersuites is to use the crypto library's default.
    50315046.\"*********************************************************
    50325047.TP
    50335048.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) 
    17661766#endif
    17671767    SHOW_STR(cipher_list);
    17681768    SHOW_STR(tls_cert_profile);
     1769    SHOW_STR(cipher_list_tls13);
    17691770    SHOW_STR(tls_verify);
    17701771    SHOW_STR(tls_export_cert);
    17711772    SHOW_INT(verify_x509_type);
    options_postprocess_verify_ce(const struct options *options, const struct connec 
    27592760        MUST_BE_UNDEF(pkcs12_file);
    27602761#endif
    27612762        MUST_BE_UNDEF(cipher_list);
     2763        MUST_BE_UNDEF(cipher_list_tls13);
    27622764        MUST_BE_UNDEF(tls_cert_profile);
    27632765        MUST_BE_UNDEF(tls_verify);
    27642766        MUST_BE_UNDEF(tls_export_cert);
    add_option(struct options *options, 
    79487950        VERIFY_PERMISSION(OPT_P_GENERAL);
    79497951        options->tls_cert_profile = p[1];
    79507952    }
     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    }
    79517958    else if (streq(p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir"))
    79527959                                                   || (p[2] && streq(p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3])
    79537960    {
  • src/openvpn/options.h

    diff --git a/src/openvpn/options.h b/src/openvpn/options.h
    index 4c3bc4fb..3e7ef4f8 100644
    a b struct options 
    508508    const char *priv_key_file;
    509509    const char *pkcs12_file;
    510510    const char *cipher_list;
     511    const char *cipher_list_tls13;
    511512    const char *tls_cert_profile;
    512513    const char *ecdh_curve;
    513514    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) 
    626626    tls_ctx_set_cert_profile(new_ctx, options->tls_cert_profile);
    627627
    628628    /* Allowable ciphers */
    629     /* Since @SECLEVEL also influces loading of certificates, set the
     629    /* Since @SECLEVEL also influences loading of certificates, set the
    630630     * cipher restrictions before loading certificates */
    631631    tls_ctx_restrict_ciphers(new_ctx, options->cipher_list);
     632    tls_ctx_restrict_ciphers_tls13(new_ctx, options->cipher_list_tls13);
    632633
    633634    if (!tls_ctx_set_options(new_ctx, options->ssl_flags))
    634635    {
  • 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); 
    169169bool tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags);
    170170
    171171/**
    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
    173174 *
    174175 * @param ctx           TLS context to restrict, must be valid.
    175176 * @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); 
    177178 */
    178179void tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers);
    179180
     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 */
     189void tls_ctx_restrict_ciphers_tls13(struct tls_root_ctx *ctx, const char *ciphers);
     190
    180191/**
    181192 * Set the TLS certificate profile.  The profile defines which crypto
    182193 * 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) 
    222222    return pair->iana_name;
    223223}
    224224
     225void
     226tls_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
    225237void
    226238tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
    227239{
  • 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) 
    322322    return true;
    323323}
    324324
     325void
     326convert_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
     397void
     398tls_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
    325422void
    326423tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
    327424{
    tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers) 
    345442        return;
    346443    }
    347444
    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 
    356445    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);
    359447
    360448    ASSERT(NULL != ctx);
    361449
    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         else
    382         {
    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_len
    388                 && 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_len
    398             || ((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 
    419450    /* Set OpenSSL cipher list */
    420451    if (!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
    421452    {