Home | History | Annotate | Download | only in ssl
      1 /* Copyright (c) 2014, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #include <openssl/ssl.h>
     16 
     17 #include <assert.h>
     18 #include <string.h>
     19 
     20 #include <openssl/bytestring.h>
     21 #include <openssl/err.h>
     22 #include <openssl/mem.h>
     23 #include <openssl/stack.h>
     24 
     25 #include "internal.h"
     26 
     27 
     28 void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) {
     29   OPENSSL_free(custom_extension);
     30 }
     31 
     32 static const SSL_CUSTOM_EXTENSION *custom_ext_find(
     33     STACK_OF(SSL_CUSTOM_EXTENSION) *stack,
     34     unsigned *out_index, uint16_t value) {
     35   for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
     36     const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
     37     if (ext->value == value) {
     38       if (out_index != NULL) {
     39         *out_index = i;
     40       }
     41       return ext;
     42     }
     43   }
     44 
     45   return NULL;
     46 }
     47 
     48 /* default_add_callback is used as the |add_callback| when the user doesn't
     49  * provide one. For servers, it does nothing while, for clients, it causes an
     50  * empty extension to be included. */
     51 static int default_add_callback(SSL *ssl, unsigned extension_value,
     52                                 const uint8_t **out, size_t *out_len,
     53                                 int *out_alert_value, void *add_arg) {
     54   if (ssl->server) {
     55     return 0;
     56   }
     57   *out_len = 0;
     58   return 1;
     59 }
     60 
     61 static int custom_ext_add_hello(SSL_HANDSHAKE *hs, CBB *extensions) {
     62   SSL *const ssl = hs->ssl;
     63   STACK_OF(SSL_CUSTOM_EXTENSION) *stack = ssl->ctx->client_custom_extensions;
     64   if (ssl->server) {
     65     stack = ssl->ctx->server_custom_extensions;
     66   }
     67 
     68   if (stack == NULL) {
     69     return 1;
     70   }
     71 
     72   if (ssl->ctx->enable_early_data) {
     73     /* TODO(svaldez): Support Custom Extensions with 0-RTT. For now the caller
     74      * is expected not to configure both together.
     75      * https://crbug.com/boringssl/173. */
     76     OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
     77     return 0;
     78   }
     79 
     80   for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
     81     const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
     82 
     83     if (ssl->server &&
     84         !(hs->custom_extensions.received & (1u << i))) {
     85       /* Servers cannot echo extensions that the client didn't send. */
     86       continue;
     87     }
     88 
     89     const uint8_t *contents;
     90     size_t contents_len;
     91     int alert = SSL_AD_DECODE_ERROR;
     92     CBB contents_cbb;
     93 
     94     switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert,
     95                               ext->add_arg)) {
     96       case 1:
     97         if (!CBB_add_u16(extensions, ext->value) ||
     98             !CBB_add_u16_length_prefixed(extensions, &contents_cbb) ||
     99             !CBB_add_bytes(&contents_cbb, contents, contents_len) ||
    100             !CBB_flush(extensions)) {
    101           OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    102           ERR_add_error_dataf("extension %u", (unsigned) ext->value);
    103           if (ext->free_callback && 0 < contents_len) {
    104             ext->free_callback(ssl, ext->value, contents, ext->add_arg);
    105           }
    106           return 0;
    107         }
    108 
    109         if (ext->free_callback && 0 < contents_len) {
    110           ext->free_callback(ssl, ext->value, contents, ext->add_arg);
    111         }
    112 
    113         if (!ssl->server) {
    114           assert((hs->custom_extensions.sent & (1u << i)) == 0);
    115           hs->custom_extensions.sent |= (1u << i);
    116         }
    117         break;
    118 
    119       case 0:
    120         break;
    121 
    122       default:
    123         ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
    124         OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    125         ERR_add_error_dataf("extension %u", (unsigned) ext->value);
    126         return 0;
    127     }
    128   }
    129 
    130   return 1;
    131 }
    132 
    133 int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions) {
    134   return custom_ext_add_hello(hs, extensions);
    135 }
    136 
    137 int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert,
    138                                  uint16_t value, const CBS *extension) {
    139   SSL *const ssl = hs->ssl;
    140   unsigned index;
    141   const SSL_CUSTOM_EXTENSION *ext =
    142       custom_ext_find(ssl->ctx->client_custom_extensions, &index, value);
    143 
    144   if (/* Unknown extensions are not allowed in a ServerHello. */
    145       ext == NULL ||
    146       /* Also, if we didn't send the extension, that's also unacceptable. */
    147       !(hs->custom_extensions.sent & (1u << index))) {
    148     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    149     ERR_add_error_dataf("extension %u", (unsigned)value);
    150     *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
    151     return 0;
    152   }
    153 
    154   if (ext->parse_callback != NULL &&
    155       !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
    156                            out_alert, ext->parse_arg)) {
    157     OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    158     ERR_add_error_dataf("extension %u", (unsigned)ext->value);
    159     return 0;
    160   }
    161 
    162   return 1;
    163 }
    164 
    165 int custom_ext_parse_clienthello(SSL_HANDSHAKE *hs, int *out_alert,
    166                                  uint16_t value, const CBS *extension) {
    167   SSL *const ssl = hs->ssl;
    168   unsigned index;
    169   const SSL_CUSTOM_EXTENSION *ext =
    170       custom_ext_find(ssl->ctx->server_custom_extensions, &index, value);
    171 
    172   if (ext == NULL) {
    173     return 1;
    174   }
    175 
    176   assert((hs->custom_extensions.received & (1u << index)) == 0);
    177   hs->custom_extensions.received |= (1u << index);
    178 
    179   if (ext->parse_callback &&
    180       !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
    181                            out_alert, ext->parse_arg)) {
    182     OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    183     ERR_add_error_dataf("extension %u", (unsigned)ext->value);
    184     return 0;
    185   }
    186 
    187   return 1;
    188 }
    189 
    190 int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions) {
    191   return custom_ext_add_hello(hs, extensions);
    192 }
    193 
    194 /* MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that
    195  * can be set on an |SSL_CTX|. It's determined by the size of the bitset used
    196  * to track when an extension has been sent. */
    197 #define MAX_NUM_CUSTOM_EXTENSIONS \
    198   (sizeof(((SSL_HANDSHAKE *)NULL)->custom_extensions.sent) * 8)
    199 
    200 static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
    201                              unsigned extension_value,
    202                              SSL_custom_ext_add_cb add_cb,
    203                              SSL_custom_ext_free_cb free_cb, void *add_arg,
    204                              SSL_custom_ext_parse_cb parse_cb,
    205                              void *parse_arg) {
    206   if (add_cb == NULL ||
    207       0xffff < extension_value ||
    208       SSL_extension_supported(extension_value) ||
    209       /* Specifying a free callback without an add callback is nonsensical
    210        * and an error. */
    211       (*stack != NULL &&
    212        (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) ||
    213         custom_ext_find(*stack, NULL, extension_value) != NULL))) {
    214     return 0;
    215   }
    216 
    217   SSL_CUSTOM_EXTENSION *ext = OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
    218   if (ext == NULL) {
    219     return 0;
    220   }
    221   ext->add_callback = add_cb;
    222   ext->add_arg = add_arg;
    223   ext->free_callback = free_cb;
    224   ext->parse_callback = parse_cb;
    225   ext->parse_arg = parse_arg;
    226   ext->value = extension_value;
    227 
    228   if (*stack == NULL) {
    229     *stack = sk_SSL_CUSTOM_EXTENSION_new_null();
    230     if (*stack == NULL) {
    231       SSL_CUSTOM_EXTENSION_free(ext);
    232       return 0;
    233     }
    234   }
    235 
    236   if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) {
    237     SSL_CUSTOM_EXTENSION_free(ext);
    238     if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) {
    239       sk_SSL_CUSTOM_EXTENSION_free(*stack);
    240       *stack = NULL;
    241     }
    242     return 0;
    243   }
    244 
    245   return 1;
    246 }
    247 
    248 int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value,
    249                                   SSL_custom_ext_add_cb add_cb,
    250                                   SSL_custom_ext_free_cb free_cb, void *add_arg,
    251                                   SSL_custom_ext_parse_cb parse_cb,
    252                                   void *parse_arg) {
    253   return custom_ext_append(&ctx->client_custom_extensions, extension_value,
    254                            add_cb ? add_cb : default_add_callback, free_cb,
    255                            add_arg, parse_cb, parse_arg);
    256 }
    257 
    258 int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value,
    259                                   SSL_custom_ext_add_cb add_cb,
    260                                   SSL_custom_ext_free_cb free_cb, void *add_arg,
    261                                   SSL_custom_ext_parse_cb parse_cb,
    262                                   void *parse_arg) {
    263   return custom_ext_append(&ctx->server_custom_extensions, extension_value,
    264                            add_cb ? add_cb : default_add_callback, free_cb,
    265                            add_arg, parse_cb, parse_arg);
    266 }
    267