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   size_t i;
     36   for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
     37     const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
     38     if (ext->value == value) {
     39       if (out_index != NULL) {
     40         *out_index = i;
     41       }
     42       return ext;
     43     }
     44   }
     45 
     46   return NULL;
     47 }
     48 
     49 /* default_add_callback is used as the |add_callback| when the user doesn't
     50  * provide one. For servers, it does nothing while, for clients, it causes an
     51  * empty extension to be included. */
     52 static int default_add_callback(SSL *ssl, unsigned extension_value,
     53                                 const uint8_t **out, size_t *out_len,
     54                                 int *out_alert_value, void *add_arg) {
     55   if (ssl->server) {
     56     return 0;
     57   }
     58   *out_len = 0;
     59   return 1;
     60 }
     61 
     62 static int custom_ext_add_hello(SSL *ssl, CBB *extensions) {
     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   size_t i;
     73   for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
     74     const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
     75 
     76     if (ssl->server &&
     77         !(ssl->s3->tmp.custom_extensions.received & (1u << i))) {
     78       /* Servers cannot echo extensions that the client didn't send. */
     79       continue;
     80     }
     81 
     82     const uint8_t *contents;
     83     size_t contents_len;
     84     int alert = SSL_AD_DECODE_ERROR;
     85     CBB contents_cbb;
     86 
     87     switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert,
     88                               ext->add_arg)) {
     89       case 1:
     90         if (!CBB_add_u16(extensions, ext->value) ||
     91             !CBB_add_u16_length_prefixed(extensions, &contents_cbb) ||
     92             !CBB_add_bytes(&contents_cbb, contents, contents_len) ||
     93             !CBB_flush(extensions)) {
     94           OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
     95           ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
     96           if (ext->free_callback && 0 < contents_len) {
     97             ext->free_callback(ssl, ext->value, contents, ext->add_arg);
     98           }
     99           return 0;
    100         }
    101 
    102         if (ext->free_callback && 0 < contents_len) {
    103           ext->free_callback(ssl, ext->value, contents, ext->add_arg);
    104         }
    105 
    106         if (!ssl->server) {
    107           assert((ssl->s3->tmp.custom_extensions.sent & (1u << i)) == 0);
    108           ssl->s3->tmp.custom_extensions.sent |= (1u << i);
    109         }
    110         break;
    111 
    112       case 0:
    113         break;
    114 
    115       default:
    116         ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
    117         OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    118         ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
    119         return 0;
    120     }
    121   }
    122 
    123   return 1;
    124 }
    125 
    126 int custom_ext_add_clienthello(SSL *ssl, CBB *extensions) {
    127   return custom_ext_add_hello(ssl, extensions);
    128 }
    129 
    130 int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
    131                                  const CBS *extension) {
    132   unsigned index;
    133   const SSL_CUSTOM_EXTENSION *ext =
    134       custom_ext_find(ssl->ctx->client_custom_extensions, &index, value);
    135 
    136   if (/* Unknown extensions are not allowed in a ServerHello. */
    137       ext == NULL ||
    138       /* Also, if we didn't send the extension, that's also unacceptable. */
    139       !(ssl->s3->tmp.custom_extensions.sent & (1u << index))) {
    140     OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
    141     ERR_add_error_dataf("extension: %u", (unsigned)value);
    142     *out_alert = SSL_AD_DECODE_ERROR;
    143     return 0;
    144   }
    145 
    146   if (ext->parse_callback != NULL &&
    147       !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
    148                            out_alert, ext->parse_arg)) {
    149     OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    150     ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
    151     return 0;
    152   }
    153 
    154   return 1;
    155 }
    156 
    157 int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
    158                                  const CBS *extension) {
    159   unsigned index;
    160   const SSL_CUSTOM_EXTENSION *ext =
    161       custom_ext_find(ssl->ctx->server_custom_extensions, &index, value);
    162 
    163   if (ext == NULL) {
    164     return 1;
    165   }
    166 
    167   assert((ssl->s3->tmp.custom_extensions.received & (1u << index)) == 0);
    168   ssl->s3->tmp.custom_extensions.received |= (1u << index);
    169 
    170   if (ext->parse_callback &&
    171       !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
    172                            out_alert, ext->parse_arg)) {
    173     OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
    174     ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
    175     return 0;
    176   }
    177 
    178   return 1;
    179 }
    180 
    181 int custom_ext_add_serverhello(SSL *ssl, CBB *extensions) {
    182   return custom_ext_add_hello(ssl, extensions);
    183 }
    184 
    185 /* MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that
    186  * can be set on an |SSL_CTX|. It's determined by the size of the bitset used
    187  * to track when an extension has been sent. */
    188 #define MAX_NUM_CUSTOM_EXTENSIONS \
    189   (sizeof(((struct ssl3_state_st *)NULL)->tmp.custom_extensions.sent) * 8)
    190 
    191 static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
    192                              unsigned extension_value,
    193                              SSL_custom_ext_add_cb add_cb,
    194                              SSL_custom_ext_free_cb free_cb, void *add_arg,
    195                              SSL_custom_ext_parse_cb parse_cb,
    196                              void *parse_arg) {
    197   if (add_cb == NULL ||
    198       0xffff < extension_value ||
    199       SSL_extension_supported(extension_value) ||
    200       /* Specifying a free callback without an add callback is nonsensical
    201        * and an error. */
    202       (*stack != NULL &&
    203        (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) ||
    204         custom_ext_find(*stack, NULL, extension_value) != NULL))) {
    205     return 0;
    206   }
    207 
    208   SSL_CUSTOM_EXTENSION *ext = OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
    209   if (ext == NULL) {
    210     return 0;
    211   }
    212   ext->add_callback = add_cb;
    213   ext->add_arg = add_arg;
    214   ext->free_callback = free_cb;
    215   ext->parse_callback = parse_cb;
    216   ext->parse_arg = parse_arg;
    217   ext->value = extension_value;
    218 
    219   if (*stack == NULL) {
    220     *stack = sk_SSL_CUSTOM_EXTENSION_new_null();
    221     if (*stack == NULL) {
    222       SSL_CUSTOM_EXTENSION_free(ext);
    223       return 0;
    224     }
    225   }
    226 
    227   if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) {
    228     SSL_CUSTOM_EXTENSION_free(ext);
    229     if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) {
    230       sk_SSL_CUSTOM_EXTENSION_free(*stack);
    231       *stack = NULL;
    232     }
    233     return 0;
    234   }
    235 
    236   return 1;
    237 }
    238 
    239 int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value,
    240                                   SSL_custom_ext_add_cb add_cb,
    241                                   SSL_custom_ext_free_cb free_cb, void *add_arg,
    242                                   SSL_custom_ext_parse_cb parse_cb,
    243                                   void *parse_arg) {
    244   return custom_ext_append(&ctx->client_custom_extensions, extension_value,
    245                            add_cb ? add_cb : default_add_callback, free_cb,
    246                            add_arg, parse_cb, parse_arg);
    247 }
    248 
    249 int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value,
    250                                   SSL_custom_ext_add_cb add_cb,
    251                                   SSL_custom_ext_free_cb free_cb, void *add_arg,
    252                                   SSL_custom_ext_parse_cb parse_cb,
    253                                   void *parse_arg) {
    254   return custom_ext_append(&ctx->server_custom_extensions, extension_value,
    255                            add_cb ? add_cb : default_add_callback, free_cb,
    256                            add_arg, parse_cb, parse_arg);
    257 }
    258