Home | History | Annotate | Line # | Download | only in statem
      1 /*
      2  * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /* Custom extension utility functions */
     11 
     12 #include <openssl/ct.h>
     13 #include "../ssl_local.h"
     14 #include "internal/cryptlib.h"
     15 #include "statem_local.h"
     16 
     17 typedef struct {
     18     void *add_arg;
     19     custom_ext_add_cb add_cb;
     20     custom_ext_free_cb free_cb;
     21 } custom_ext_add_cb_wrap;
     22 
     23 typedef struct {
     24     void *parse_arg;
     25     custom_ext_parse_cb parse_cb;
     26 } custom_ext_parse_cb_wrap;
     27 
     28 /*
     29  * Provide thin wrapper callbacks which convert new style arguments to old style
     30  */
     31 static int custom_ext_add_old_cb_wrap(SSL *s, unsigned int ext_type,
     32                                       unsigned int context,
     33                                       const unsigned char **out,
     34                                       size_t *outlen, X509 *x, size_t chainidx,
     35                                       int *al, void *add_arg)
     36 {
     37     custom_ext_add_cb_wrap *add_cb_wrap = (custom_ext_add_cb_wrap *)add_arg;
     38 
     39     if (add_cb_wrap->add_cb == NULL)
     40         return 1;
     41 
     42     return add_cb_wrap->add_cb(s, ext_type, out, outlen, al,
     43                                add_cb_wrap->add_arg);
     44 }
     45 
     46 static void custom_ext_free_old_cb_wrap(SSL *s, unsigned int ext_type,
     47                                         unsigned int context,
     48                                         const unsigned char *out, void *add_arg)
     49 {
     50     custom_ext_add_cb_wrap *add_cb_wrap = (custom_ext_add_cb_wrap *)add_arg;
     51 
     52     if (add_cb_wrap->free_cb == NULL)
     53         return;
     54 
     55     add_cb_wrap->free_cb(s, ext_type, out, add_cb_wrap->add_arg);
     56 }
     57 
     58 static int custom_ext_parse_old_cb_wrap(SSL *s, unsigned int ext_type,
     59                                         unsigned int context,
     60                                         const unsigned char *in,
     61                                         size_t inlen, X509 *x, size_t chainidx,
     62                                         int *al, void *parse_arg)
     63 {
     64     custom_ext_parse_cb_wrap *parse_cb_wrap =
     65         (custom_ext_parse_cb_wrap *)parse_arg;
     66 
     67     if (parse_cb_wrap->parse_cb == NULL)
     68         return 1;
     69 
     70     return parse_cb_wrap->parse_cb(s, ext_type, in, inlen, al,
     71                                    parse_cb_wrap->parse_arg);
     72 }
     73 
     74 /*
     75  * Find a custom extension from the list. The |role| param is there to
     76  * support the legacy API where custom extensions for client and server could
     77  * be set independently on the same SSL_CTX. It is set to ENDPOINT_SERVER if we
     78  * are trying to find a method relevant to the server, ENDPOINT_CLIENT for the
     79  * client, or ENDPOINT_BOTH for either
     80  */
     81 custom_ext_method *custom_ext_find(const custom_ext_methods *exts,
     82                                    ENDPOINT role, unsigned int ext_type,
     83                                    size_t *idx)
     84 {
     85     size_t i;
     86     custom_ext_method *meth = exts->meths;
     87 
     88     for (i = 0; i < exts->meths_count; i++, meth++) {
     89         if (ext_type == meth->ext_type
     90                 && (role == ENDPOINT_BOTH || role == meth->role
     91                     || meth->role == ENDPOINT_BOTH)) {
     92             if (idx != NULL)
     93                 *idx = i;
     94             return meth;
     95         }
     96     }
     97     return NULL;
     98 }
     99 
    100 /*
    101  * Initialise custom extensions flags to indicate neither sent nor received.
    102  */
    103 void custom_ext_init(custom_ext_methods *exts)
    104 {
    105     size_t i;
    106     custom_ext_method *meth = exts->meths;
    107 
    108     for (i = 0; i < exts->meths_count; i++, meth++)
    109         meth->ext_flags = 0;
    110 }
    111 
    112 /* Pass received custom extension data to the application for parsing. */
    113 int custom_ext_parse(SSL *s, unsigned int context, unsigned int ext_type,
    114                      const unsigned char *ext_data, size_t ext_size, X509 *x,
    115                      size_t chainidx)
    116 {
    117     int al;
    118     custom_ext_methods *exts = &s->cert->custext;
    119     custom_ext_method *meth;
    120     ENDPOINT role = ENDPOINT_BOTH;
    121 
    122     if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0)
    123         role = s->server ? ENDPOINT_SERVER : ENDPOINT_CLIENT;
    124 
    125     meth = custom_ext_find(exts, role, ext_type, NULL);
    126     /* If not found return success */
    127     if (!meth)
    128         return 1;
    129 
    130     /* Check if extension is defined for our protocol. If not, skip */
    131     if (!extension_is_relevant(s, meth->context, context))
    132         return 1;
    133 
    134     if ((context & (SSL_EXT_TLS1_2_SERVER_HELLO
    135                     | SSL_EXT_TLS1_3_SERVER_HELLO
    136                     | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS)) != 0) {
    137         /*
    138          * If it's ServerHello or EncryptedExtensions we can't have any
    139          * extensions not sent in ClientHello.
    140          */
    141         if ((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0) {
    142             SSLfatal(s, TLS1_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION);
    143             return 0;
    144         }
    145     }
    146 
    147     /*
    148      * Extensions received in the ClientHello or CertificateRequest are marked
    149      * with the SSL_EXT_FLAG_RECEIVED. This is so we know to add the equivalent
    150      * extensions in the response messages
    151      */
    152     if ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST))
    153             != 0)
    154         meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
    155 
    156     /* If no parse function set return success */
    157     if (!meth->parse_cb)
    158         return 1;
    159 
    160     if (meth->parse_cb(s, ext_type, context, ext_data, ext_size, x, chainidx,
    161                        &al, meth->parse_arg) <= 0) {
    162         SSLfatal(s, al, SSL_R_BAD_EXTENSION);
    163         return 0;
    164     }
    165 
    166     return 1;
    167 }
    168 
    169 /*
    170  * Request custom extension data from the application and add to the return
    171  * buffer.
    172  */
    173 int custom_ext_add(SSL *s, int context, WPACKET *pkt, X509 *x, size_t chainidx,
    174                    int maxversion)
    175 {
    176     custom_ext_methods *exts = &s->cert->custext;
    177     custom_ext_method *meth;
    178     size_t i;
    179     int al;
    180 
    181     for (i = 0; i < exts->meths_count; i++) {
    182         const unsigned char *out = NULL;
    183         size_t outlen = 0;
    184 
    185         meth = exts->meths + i;
    186 
    187         if (!should_add_extension(s, meth->context, context, maxversion))
    188             continue;
    189 
    190         if ((context & (SSL_EXT_TLS1_2_SERVER_HELLO
    191                         | SSL_EXT_TLS1_3_SERVER_HELLO
    192                         | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS
    193                         | SSL_EXT_TLS1_3_CERTIFICATE
    194                         | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST)) != 0) {
    195             /* Only send extensions present in ClientHello/CertificateRequest */
    196             if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED))
    197                 continue;
    198         }
    199         /*
    200          * We skip it if the callback is absent - except for a ClientHello where
    201          * we add an empty extension.
    202          */
    203         if ((context & SSL_EXT_CLIENT_HELLO) == 0 && meth->add_cb == NULL)
    204             continue;
    205 
    206         if (meth->add_cb != NULL) {
    207             int cb_retval = meth->add_cb(s, meth->ext_type, context, &out,
    208                                          &outlen, x, chainidx, &al,
    209                                          meth->add_arg);
    210 
    211             if (cb_retval < 0) {
    212                 SSLfatal(s, al, SSL_R_CALLBACK_FAILED);
    213                 return 0;       /* error */
    214             }
    215             if (cb_retval == 0)
    216                 continue;       /* skip this extension */
    217         }
    218 
    219         if (!WPACKET_put_bytes_u16(pkt, meth->ext_type)
    220                 || !WPACKET_start_sub_packet_u16(pkt)
    221                 || (outlen > 0 && !WPACKET_memcpy(pkt, out, outlen))
    222                 || !WPACKET_close(pkt)) {
    223             if (meth->free_cb != NULL)
    224                 meth->free_cb(s, meth->ext_type, context, out, meth->add_arg);
    225             SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
    226             return 0;
    227         }
    228         if ((context & SSL_EXT_CLIENT_HELLO) != 0) {
    229             /*
    230              * We can't send duplicates: code logic should prevent this.
    231              */
    232             if (!ossl_assert((meth->ext_flags & SSL_EXT_FLAG_SENT) == 0)) {
    233                 if (meth->free_cb != NULL)
    234                     meth->free_cb(s, meth->ext_type, context, out,
    235                                   meth->add_arg);
    236                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
    237                 return 0;
    238             }
    239             /*
    240              * Indicate extension has been sent: this is both a sanity check to
    241              * ensure we don't send duplicate extensions and indicates that it
    242              * is not an error if the extension is present in ServerHello.
    243              */
    244             meth->ext_flags |= SSL_EXT_FLAG_SENT;
    245         }
    246         if (meth->free_cb != NULL)
    247             meth->free_cb(s, meth->ext_type, context, out, meth->add_arg);
    248     }
    249     return 1;
    250 }
    251 
    252 /* Copy the flags from src to dst for any extensions that exist in both */
    253 int custom_exts_copy_flags(custom_ext_methods *dst,
    254                            const custom_ext_methods *src)
    255 {
    256     size_t i;
    257     custom_ext_method *methsrc = src->meths;
    258 
    259     for (i = 0; i < src->meths_count; i++, methsrc++) {
    260         custom_ext_method *methdst = custom_ext_find(dst, methsrc->role,
    261                                                      methsrc->ext_type, NULL);
    262 
    263         if (methdst == NULL)
    264             continue;
    265 
    266         methdst->ext_flags = methsrc->ext_flags;
    267     }
    268 
    269     return 1;
    270 }
    271 
    272 /* Copy table of custom extensions */
    273 int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
    274 {
    275     size_t i;
    276     int err = 0;
    277 
    278     if (src->meths_count > 0) {
    279         dst->meths =
    280             OPENSSL_memdup(src->meths,
    281                            sizeof(*src->meths) * src->meths_count);
    282         if (dst->meths == NULL)
    283             return 0;
    284         dst->meths_count = src->meths_count;
    285 
    286         for (i = 0; i < src->meths_count; i++) {
    287             custom_ext_method *methsrc = src->meths + i;
    288             custom_ext_method *methdst = dst->meths + i;
    289 
    290             if (methsrc->add_cb != custom_ext_add_old_cb_wrap)
    291                 continue;
    292 
    293             /*
    294              * We have found an old style API wrapper. We need to copy the
    295              * arguments too.
    296              */
    297 
    298             if (err) {
    299                 methdst->add_arg = NULL;
    300                 methdst->parse_arg = NULL;
    301                 continue;
    302             }
    303 
    304             methdst->add_arg = OPENSSL_memdup(methsrc->add_arg,
    305                                               sizeof(custom_ext_add_cb_wrap));
    306             methdst->parse_arg = OPENSSL_memdup(methsrc->parse_arg,
    307                                             sizeof(custom_ext_parse_cb_wrap));
    308 
    309             if (methdst->add_arg == NULL || methdst->parse_arg == NULL)
    310                 err = 1;
    311         }
    312     }
    313 
    314     if (err) {
    315         custom_exts_free(dst);
    316         return 0;
    317     }
    318 
    319     return 1;
    320 }
    321 
    322 void custom_exts_free(custom_ext_methods *exts)
    323 {
    324     size_t i;
    325     custom_ext_method *meth;
    326 
    327     for (i = 0, meth = exts->meths; i < exts->meths_count; i++, meth++) {
    328         if (meth->add_cb != custom_ext_add_old_cb_wrap)
    329             continue;
    330 
    331         /* Old style API wrapper. Need to free the arguments too */
    332         OPENSSL_free(meth->add_arg);
    333         OPENSSL_free(meth->parse_arg);
    334     }
    335     OPENSSL_free(exts->meths);
    336     exts->meths = NULL;
    337     exts->meths_count = 0;
    338 }
    339 
    340 /* Return true if a client custom extension exists, false otherwise */
    341 int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
    342 {
    343     return custom_ext_find(&ctx->cert->custext, ENDPOINT_CLIENT, ext_type,
    344                            NULL) != NULL;
    345 }
    346 
    347 static int add_custom_ext_intern(SSL_CTX *ctx, ENDPOINT role,
    348                                  unsigned int ext_type,
    349                                  unsigned int context,
    350                                  SSL_custom_ext_add_cb_ex add_cb,
    351                                  SSL_custom_ext_free_cb_ex free_cb,
    352                                  void *add_arg,
    353                                  SSL_custom_ext_parse_cb_ex parse_cb,
    354                                  void *parse_arg)
    355 {
    356     custom_ext_methods *exts = &ctx->cert->custext;
    357     custom_ext_method *meth, *tmp;
    358 
    359     /*
    360      * Check application error: if add_cb is not set free_cb will never be
    361      * called.
    362      */
    363     if (add_cb == NULL && free_cb != NULL)
    364         return 0;
    365 
    366 #ifndef OPENSSL_NO_CT
    367     /*
    368      * We don't want applications registering callbacks for SCT extensions
    369      * whilst simultaneously using the built-in SCT validation features, as
    370      * these two things may not play well together.
    371      */
    372     if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp
    373             && (context & SSL_EXT_CLIENT_HELLO) != 0
    374             && SSL_CTX_ct_is_enabled(ctx))
    375         return 0;
    376 #endif
    377 
    378     /*
    379      * Don't add if extension supported internally, but make exception
    380      * for extension types that previously were not supported, but now are.
    381      */
    382     if (SSL_extension_supported(ext_type)
    383             && ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
    384         return 0;
    385 
    386     /* Extension type must fit in 16 bits */
    387     if (ext_type > 0xffff)
    388         return 0;
    389     /* Search for duplicate */
    390     if (custom_ext_find(exts, role, ext_type, NULL))
    391         return 0;
    392     tmp = OPENSSL_realloc(exts->meths,
    393                           (exts->meths_count + 1) * sizeof(custom_ext_method));
    394     if (tmp == NULL)
    395         return 0;
    396 
    397     exts->meths = tmp;
    398     meth = exts->meths + exts->meths_count;
    399     memset(meth, 0, sizeof(*meth));
    400     meth->role = role;
    401     meth->context = context;
    402     meth->parse_cb = parse_cb;
    403     meth->add_cb = add_cb;
    404     meth->free_cb = free_cb;
    405     meth->ext_type = ext_type;
    406     meth->add_arg = add_arg;
    407     meth->parse_arg = parse_arg;
    408     exts->meths_count++;
    409     return 1;
    410 }
    411 
    412 static int add_old_custom_ext(SSL_CTX *ctx, ENDPOINT role,
    413                               unsigned int ext_type,
    414                               unsigned int context,
    415                               custom_ext_add_cb add_cb,
    416                               custom_ext_free_cb free_cb,
    417                               void *add_arg,
    418                               custom_ext_parse_cb parse_cb, void *parse_arg)
    419 {
    420     custom_ext_add_cb_wrap *add_cb_wrap
    421         = OPENSSL_malloc(sizeof(*add_cb_wrap));
    422     custom_ext_parse_cb_wrap *parse_cb_wrap
    423         = OPENSSL_malloc(sizeof(*parse_cb_wrap));
    424     int ret;
    425 
    426     if (add_cb_wrap == NULL || parse_cb_wrap == NULL) {
    427         OPENSSL_free(add_cb_wrap);
    428         OPENSSL_free(parse_cb_wrap);
    429         return 0;
    430     }
    431 
    432     add_cb_wrap->add_arg = add_arg;
    433     add_cb_wrap->add_cb = add_cb;
    434     add_cb_wrap->free_cb = free_cb;
    435     parse_cb_wrap->parse_arg = parse_arg;
    436     parse_cb_wrap->parse_cb = parse_cb;
    437 
    438     ret = add_custom_ext_intern(ctx, role, ext_type,
    439                                 context,
    440                                 custom_ext_add_old_cb_wrap,
    441                                 custom_ext_free_old_cb_wrap,
    442                                 add_cb_wrap,
    443                                 custom_ext_parse_old_cb_wrap,
    444                                 parse_cb_wrap);
    445 
    446     if (!ret) {
    447         OPENSSL_free(add_cb_wrap);
    448         OPENSSL_free(parse_cb_wrap);
    449     }
    450 
    451     return ret;
    452 }
    453 
    454 /* Application level functions to add the old custom extension callbacks */
    455 int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
    456                                   custom_ext_add_cb add_cb,
    457                                   custom_ext_free_cb free_cb,
    458                                   void *add_arg,
    459                                   custom_ext_parse_cb parse_cb, void *parse_arg)
    460 {
    461     return add_old_custom_ext(ctx, ENDPOINT_CLIENT, ext_type,
    462                               SSL_EXT_TLS1_2_AND_BELOW_ONLY
    463                               | SSL_EXT_CLIENT_HELLO
    464                               | SSL_EXT_TLS1_2_SERVER_HELLO
    465                               | SSL_EXT_IGNORE_ON_RESUMPTION,
    466                               add_cb, free_cb, add_arg, parse_cb, parse_arg);
    467 }
    468 
    469 int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
    470                                   custom_ext_add_cb add_cb,
    471                                   custom_ext_free_cb free_cb,
    472                                   void *add_arg,
    473                                   custom_ext_parse_cb parse_cb, void *parse_arg)
    474 {
    475     return add_old_custom_ext(ctx, ENDPOINT_SERVER, ext_type,
    476                               SSL_EXT_TLS1_2_AND_BELOW_ONLY
    477                               | SSL_EXT_CLIENT_HELLO
    478                               | SSL_EXT_TLS1_2_SERVER_HELLO
    479                               | SSL_EXT_IGNORE_ON_RESUMPTION,
    480                               add_cb, free_cb, add_arg, parse_cb, parse_arg);
    481 }
    482 
    483 int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
    484                            unsigned int context,
    485                            SSL_custom_ext_add_cb_ex add_cb,
    486                            SSL_custom_ext_free_cb_ex free_cb,
    487                            void *add_arg,
    488                            SSL_custom_ext_parse_cb_ex parse_cb, void *parse_arg)
    489 {
    490     return add_custom_ext_intern(ctx, ENDPOINT_BOTH, ext_type, context, add_cb,
    491                                  free_cb, add_arg, parse_cb, parse_arg);
    492 }
    493 
    494 int SSL_extension_supported(unsigned int ext_type)
    495 {
    496     switch (ext_type) {
    497         /* Internally supported extensions. */
    498     case TLSEXT_TYPE_application_layer_protocol_negotiation:
    499     case TLSEXT_TYPE_ec_point_formats:
    500     case TLSEXT_TYPE_supported_groups:
    501     case TLSEXT_TYPE_key_share:
    502 #ifndef OPENSSL_NO_NEXTPROTONEG
    503     case TLSEXT_TYPE_next_proto_neg:
    504 #endif
    505     case TLSEXT_TYPE_padding:
    506     case TLSEXT_TYPE_renegotiate:
    507     case TLSEXT_TYPE_max_fragment_length:
    508     case TLSEXT_TYPE_server_name:
    509     case TLSEXT_TYPE_session_ticket:
    510     case TLSEXT_TYPE_signature_algorithms:
    511 #ifndef OPENSSL_NO_SRP
    512     case TLSEXT_TYPE_srp:
    513 #endif
    514 #ifndef OPENSSL_NO_OCSP
    515     case TLSEXT_TYPE_status_request:
    516 #endif
    517 #ifndef OPENSSL_NO_CT
    518     case TLSEXT_TYPE_signed_certificate_timestamp:
    519 #endif
    520 #ifndef OPENSSL_NO_SRTP
    521     case TLSEXT_TYPE_use_srtp:
    522 #endif
    523     case TLSEXT_TYPE_encrypt_then_mac:
    524     case TLSEXT_TYPE_supported_versions:
    525     case TLSEXT_TYPE_extended_master_secret:
    526     case TLSEXT_TYPE_psk_kex_modes:
    527     case TLSEXT_TYPE_cookie:
    528     case TLSEXT_TYPE_early_data:
    529     case TLSEXT_TYPE_certificate_authorities:
    530     case TLSEXT_TYPE_psk:
    531     case TLSEXT_TYPE_post_handshake_auth:
    532         return 1;
    533     default:
    534         return 0;
    535     }
    536 }
    537