ssl_srv.c 119 KB
Newer Older
1 2 3
/*
 *  SSLv3/TLSv1 server-side functions
 *
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
4
 *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakker's avatar
Paul Bakker committed
5
 *
6
 *  This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker's avatar
Paul Bakker committed
7
 *
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
23
#if !defined(MBEDTLS_CONFIG_FILE)
24
#include "mbedtls/config.h"
25
#else
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
26
#include MBEDTLS_CONFIG_FILE
27
#endif
28

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
29
#if defined(MBEDTLS_SSL_SRV_C)
30

31 32
#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
33
#include "mbedtls/ssl_internal.h"
34 35 36

#include <string.h>

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
37
#if defined(MBEDTLS_ECP_C)
38
#include "mbedtls/ecp.h"
39
#endif
40

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
41
#if defined(MBEDTLS_PLATFORM_C)
42
#include "mbedtls/platform.h"
43
#else
44
#include <stdlib.h>
45
#define mbedtls_calloc    calloc
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
46
#define mbedtls_free       free
47 48
#endif

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
49
#if defined(MBEDTLS_HAVE_TIME)
50
#include <time.h>
51
#endif
52

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
53
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
54 55 56 57
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
58 59
#endif

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
60 61
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl,
62 63 64
                                 const unsigned char *info,
                                 size_t ilen )
{
65
    if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
66
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
67

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
68
    mbedtls_free( ssl->cli_id );
69

70
    if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL )
71
        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
72 73 74 75 76 77

    memcpy( ssl->cli_id, info, ilen );
    ssl->cli_id_len = ilen;

    return( 0 );
}
78

79
void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf,
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
80 81
                           mbedtls_ssl_cookie_write_t *f_cookie_write,
                           mbedtls_ssl_cookie_check_t *f_cookie_check,
82 83
                           void *p_cookie )
{
84 85 86
    conf->f_cookie_write = f_cookie_write;
    conf->f_cookie_check = f_cookie_check;
    conf->p_cookie       = p_cookie;
87
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
88
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
89

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
90 91
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
92
                                     const unsigned char *buf,
93 94 95 96
                                     size_t len )
{
    int ret;
    size_t servername_list_size, hostname_len;
97
    const unsigned char *p;
98

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
99
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
100

101 102 103
    servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
    if( servername_list_size + 2 != len )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
104 105
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
106 107 108 109 110 111 112 113
    }

    p = buf + 2;
    while( servername_list_size > 0 )
    {
        hostname_len = ( ( p[1] << 8 ) | p[2] );
        if( hostname_len + 3 > servername_list_size )
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
114 115
            MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
116 117
        }

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
118
        if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME )
119
        {
120 121
            ret = ssl->conf->f_sni( ssl->conf->p_sni,
                                    ssl, p + 3, hostname_len );
122 123
            if( ret != 0 )
            {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
124 125 126 127
                MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret );
                mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                        MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME );
                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
128
            }
129
            return( 0 );
130 131 132
        }

        servername_list_size -= hostname_len + 3;
133 134 135 136 137
        p += hostname_len + 3;
    }

    if( servername_list_size != 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
138 139
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
140 141 142 143
    }

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
144
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
145

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
146
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
147
                                         const unsigned char *buf,
148 149
                                         size_t len )
{
150 151
    int ret;

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
152 153
#if defined(MBEDTLS_SSL_RENEGOTIATION)
    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
154
    {
155 156 157
        /* Check verify-data in constant-time. The length OTOH is no secret */
        if( len    != 1 + ssl->verify_data_len ||
            buf[0] !=     ssl->verify_data_len ||
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
158
            mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
159
                          ssl->verify_data_len ) != 0 )
160
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
161
            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
162

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
163
            if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
164 165
                return( ret );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
166
            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
167 168 169
        }
    }
    else
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
170
#endif /* MBEDTLS_SSL_RENEGOTIATION */
171
    {
172
        if( len != 1 || buf[0] != 0x0 )
173
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
174
            MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) );
175

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
176
            if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
177 178
                return( ret );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
179
            return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
180
        }
181

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
182
        ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
183 184 185 186 187
    }

    return( 0 );
}

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
188 189 190
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
    defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
191 192 193 194 195
                                               const unsigned char *buf,
                                               size_t len )
{
    size_t sig_alg_list_size;
    const unsigned char *p;
196 197 198
    const unsigned char *end = buf + len;
    const int *md_cur;

199 200 201

    sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
    if( sig_alg_list_size + 2 != len ||
202
        sig_alg_list_size % 2 != 0 )
203
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
204 205
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
206 207
    }

208 209 210 211 212 213
    /*
     * For now, ignore the SignatureAlgorithm part and rely on offered
     * ciphersuites only for that part. To be fixed later.
     *
     * So, just look at the HashAlgorithm part.
     */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
214
    for( md_cur = mbedtls_md_list(); *md_cur != MBEDTLS_MD_NONE; md_cur++ ) {
215
        for( p = buf + 2; p < end; p += 2 ) {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
216
            if( *md_cur == (int) mbedtls_ssl_md_alg_from_hash( p[0] ) ) {
217
                ssl->handshake->sig_alg = p[0];
218
                goto have_sig_alg;
219
            }
220 221 222
        }
    }

223
    /* Some key echanges do not need signatures at all */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
224
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) );
225 226 227
    return( 0 );

have_sig_alg:
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
228
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d",
229 230 231 232
                   ssl->handshake->sig_alg ) );

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
233 234
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
          MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
235

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
236 237
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
238 239
                                                const unsigned char *buf,
                                                size_t len )
240
{
241
    size_t list_size, our_size;
242
    const unsigned char *p;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
243
    const mbedtls_ecp_curve_info *curve_info, **curves;
244 245 246 247 248

    list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
    if( list_size + 2 != len ||
        list_size % 2 != 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
249 250
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
251 252
    }

253 254 255
    /* Should never happen unless client duplicates the extension */
    if( ssl->handshake->curves != NULL )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
256 257
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
258 259
    }

260
    /* Don't allow our peer to make us allocate too much memory,
261 262
     * and leave room for a final 0 */
    our_size = list_size / 2 + 1;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
263 264
    if( our_size > MBEDTLS_ECP_DP_MAX )
        our_size = MBEDTLS_ECP_DP_MAX;
265

266
    if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL )
267
        return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
268 269 270

    ssl->handshake->curves = curves;

271
    p = buf + 2;
272
    while( list_size > 0 && our_size > 1 )
273
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
274
        curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] );
275

276
        if( curve_info != NULL )
277
        {
278 279
            *curves++ = curve_info;
            our_size--;
280
        }
281 282 283 284 285 286 287 288

        list_size -= 2;
        p += 2;
    }

    return( 0 );
}

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
289
static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
290 291
                                              const unsigned char *buf,
                                              size_t len )
292 293 294 295 296 297 298
{
    size_t list_size;
    const unsigned char *p;

    list_size = buf[0];
    if( list_size + 1 != len )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
299 300
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
301 302 303 304 305
    }

    p = buf + 2;
    while( list_size > 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
306 307
        if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
            p[0] == MBEDTLS_ECP_PF_COMPRESSED )
308
        {
309
            ssl->handshake->ecdh_ctx.point_format = p[0];
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
310
            MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
311 312 313 314 315 316 317 318 319
            return( 0 );
        }

        list_size--;
        p++;
    }

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
320
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
321

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
322 323
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
324 325 326
                                              const unsigned char *buf,
                                              size_t len )
{
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
327
    if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID )
328
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
329 330
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
331 332
    }

333 334
    ssl->session_negotiate->mfl_code = buf[0];

335 336
    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
337
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
338

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
339 340
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
341 342 343 344 345
                                         const unsigned char *buf,
                                         size_t len )
{
    if( len != 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
346 347
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
348 349 350 351
    }

    ((void) buf);

352
    if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
353
        ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED;
354 355 356

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
357
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
358

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
359 360
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
361 362 363 364 365
                                      const unsigned char *buf,
                                      size_t len )
{
    if( len != 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
366 367
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
368 369 370 371
    }

    ((void) buf);

372
    if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED &&
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
373
        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
374
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
375
        ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
376 377 378 379
    }

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
380
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
381

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
382 383
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl,
384 385 386 387 388
                                      const unsigned char *buf,
                                      size_t len )
{
    if( len != 0 )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
389 390
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
391 392 393 394
    }

    ((void) buf);

395
    if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED &&
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
396
        ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
397
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
398
        ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
399
    }
400 401 402

    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
403
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
404

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
405 406
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
407
                                         unsigned char *buf,
408 409
                                         size_t len )
{
410
    int ret;
411
    mbedtls_ssl_session session;
412

413 414 415
    if( ssl->conf->f_ticket_parse == NULL ||
        ssl->conf->f_ticket_write == NULL )
    {
416
        return( 0 );
417
    }
418

419
    /* Remember the client asked us to send a new ticket */
420 421
    ssl->handshake->new_session_ticket = 1;

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
422
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
423

424 425 426
    if( len == 0 )
        return( 0 );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
427 428
#if defined(MBEDTLS_SSL_RENEGOTIATION)
    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
429
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
430
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) );
431 432
        return( 0 );
    }
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
433
#endif /* MBEDTLS_SSL_RENEGOTIATION */
434 435 436 437

    /*
     * Failures are ok: just ignore the ticket and proceed.
     */
438 439
    if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session,
                                           buf, len ) ) != 0 )
440
    {
441
        mbedtls_ssl_session_free( &session );
442 443 444 445 446 447 448 449

        if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) );
        else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED )
            MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) );
        else
            MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret );

450
        return( 0 );
451
    }
452

453 454 455 456 457 458 459 460 461 462 463 464 465
    /*
     * Keep the session ID sent by the client, since we MUST send it back to
     * inform them we're accepting the ticket  (RFC 5077 section 3.4)
     */
    session.length = ssl->session_negotiate->length;
    memcpy( &session.id, ssl->session_negotiate->id, session.length );

    mbedtls_ssl_session_free( ssl->session_negotiate );
    memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) );

    /* Zeroize instead of free as we copied the content */
    mbedtls_zeroize( &session, sizeof( mbedtls_ssl_session ) );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
466
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) );
467 468

    ssl->handshake->resume = 1;
469

470 471 472
    /* Don't send a new ticket after all, this one is OK */
    ssl->handshake->new_session_ticket = 0;

473 474
    return( 0 );
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
475
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
476

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
477 478
#if defined(MBEDTLS_SSL_ALPN)
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
479
                               const unsigned char *buf, size_t len )
480
{
481
    size_t list_len, cur_len, ours_len;
482 483 484 485
    const unsigned char *theirs, *start, *end;
    const char **ours;

    /* If ALPN not configured, just ignore the extension */
486
    if( ssl->conf->alpn_list == NULL )
487 488 489 490 491 492 493 494 495 496 497 498
        return( 0 );

    /*
     * opaque ProtocolName<1..2^8-1>;
     *
     * struct {
     *     ProtocolName protocol_name_list<2..2^16-1>
     * } ProtocolNameList;
     */

    /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
    if( len < 4 )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
499
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
500 501 502

    list_len = ( buf[0] << 8 ) | buf[1];
    if( list_len != len - 2 )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
503
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
504 505 506 507 508 509

    /*
     * Use our order of preference
     */
    start = buf + 2;
    end = buf + len;
510
    for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
511
    {
512
        ours_len = strlen( *ours );
513 514 515 516
        for( theirs = start; theirs != end; theirs += cur_len )
        {
            /* If the list is well formed, we should get equality first */
            if( theirs > end )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
517
                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
518 519 520 521 522

            cur_len = *theirs++;

            /* Empty strings MUST NOT be included */
            if( cur_len == 0 )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
523
                return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
524

525
            if( cur_len == ours_len &&
526 527 528 529 530 531 532 533 534
                memcmp( theirs, *ours, cur_len ) == 0 )
            {
                ssl->alpn_chosen = *ours;
                return( 0 );
            }
        }
    }

    /* If we get there, no match was found */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
535 536 537
    mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
                            MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL );
    return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
538
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
539
#endif /* MBEDTLS_SSL_ALPN */
540

541 542 543 544
/*
 * Auxiliary functions for ServerHello parsing and related actions
 */

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
545
#if defined(MBEDTLS_X509_CRT_PARSE_C)
546
/*
547
 * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
548
 */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
549 550 551
#if defined(MBEDTLS_ECDSA_C)
static int ssl_check_key_curve( mbedtls_pk_context *pk,
                                const mbedtls_ecp_curve_info **curves )
552
{
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
553 554
    const mbedtls_ecp_curve_info **crv = curves;
    mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id;
555 556 557 558

    while( *crv != NULL )
    {
        if( (*crv)->grp_id == grp_id )
559
            return( 0 );
560 561 562
        crv++;
    }

563
    return( -1 );
564
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
565
#endif /* MBEDTLS_ECDSA_C */
566 567 568 569 570

/*
 * Try picking a certificate for this ciphersuite,
 * return 0 on success and -1 on failure.
 */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
571 572
static int ssl_pick_cert( mbedtls_ssl_context *ssl,
                          const mbedtls_ssl_ciphersuite_t * ciphersuite_info )
573
{
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
574 575
    mbedtls_ssl_key_cert *cur, *list, *fallback = NULL;
    mbedtls_pk_type_t pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
576
    uint32_t flags;
577

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
578
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
579 580 581 582
    if( ssl->handshake->sni_key_cert != NULL )
        list = ssl->handshake->sni_key_cert;
    else
#endif
583
        list = ssl->conf->key_cert;
584

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
585
    if( pk_alg == MBEDTLS_PK_NONE )
586 587
        return( 0 );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
588
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) );
589

590 591
    for( cur = list; cur != NULL; cur = cur->next )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
592
        MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
593 594
                          cur->cert );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
595
        if( ! mbedtls_pk_can_do( cur->key, pk_alg ) )
596
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
597
            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
598
            continue;
599
        }
600

601 602 603 604 605 606 607 608
        /*
         * This avoids sending the client a cert it'll reject based on
         * keyUsage or other extensions.
         *
         * It also allows the user to provision different certificates for
         * different uses based on keyUsage, eg if they want to avoid signing
         * and decrypting with the same RSA key.
         */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
609
        if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info,
610
                                  MBEDTLS_SSL_IS_SERVER, &flags ) != 0 )
611
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
612
            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
613
                                "(extended) key usage extension" ) );
614 615 616
            continue;
        }

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
617 618
#if defined(MBEDTLS_ECDSA_C)
        if( pk_alg == MBEDTLS_PK_ECDSA &&
619
            ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 )
620
        {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
621
            MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
622
            continue;
623
        }
624
#endif
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
625

626 627 628 629 630
        /*
         * Try to select a SHA-1 certificate for pre-1.2 clients, but still
         * present them a SHA-higher cert rather than failing if it's the only
         * one we got that satisfies the other conditions.
         */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
631 632
        if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 &&
            cur->cert->sig_md != MBEDTLS_MD_SHA1 )
633
        {
634 635
            if( fallback == NULL )
                fallback = cur;
636
            {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
637
                MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: "
638
                                    "sha-2 with pre-TLS 1.2 client" ) );
639
            continue;
640
            }
641
        }
642

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
643 644
        /* If we get there, we got a winner */
        break;
645 646
    }

647 648 649 650
    if( cur == NULL )
        cur = fallback;


651
    /* Do not update ssl->handshake->key_cert unless there is a match */
652 653 654
    if( cur != NULL )
    {
        ssl->handshake->key_cert = cur;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
655
        MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate",
656
                          ssl->handshake->key_cert->cert );
657 658 659 660
        return( 0 );
    }

    return( -1 );
661
}
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
662
#endif /* MBEDTLS_X509_CRT_PARSE_C */
663 664 665 666 667

/*
 * Check if a given ciphersuite is suitable for use with our config/keys/etc
 * Sets ciphersuite_info only if the suite matches.
 */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
668 669
static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
                                  const mbedtls_ssl_ciphersuite_t **ciphersuite_info )
670
{
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
671
    const mbedtls_ssl_ciphersuite_t *suite_info;
672

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
673
    suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id );
674 675
    if( suite_info == NULL )
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
676 677
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
        return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
678 679
    }

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
680
    MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
681

682 683
    if( suite_info->min_minor_ver > ssl->minor_ver ||
        suite_info->max_minor_ver < ssl->minor_ver )
684
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
685
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) );
686
        return( 0 );
687
    }
688

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
689
#if defined(MBEDTLS_SSL_PROTO_DTLS)
690
    if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
691
        ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
692 693 694
        return( 0 );
#endif

695
#if defined(MBEDTLS_ARC4_C)
696
    if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
697
            suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
698
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
699
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) );
700
        return( 0 );
701
    }
702
#endif
703

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
704 705
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
    if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
706 707
        ( ssl->handshake->curves == NULL ||
          ssl->handshake->curves[0] == NULL ) )
708
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
709
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
710
                            "no common elliptic curve" ) );
711
        return( 0 );
712
    }
713 714
#endif

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
715
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
716 717
    /* If the ciphersuite requires a pre-shared key and we don't
     * have one, skip it now rather than failing later */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
718
    if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
719 720 721
        ssl->conf->f_psk == NULL &&
        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
722
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
723
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
724
        return( 0 );
725
    }
726 727
#endif

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
728
#if defined(MBEDTLS_X509_CRT_PARSE_C)
729 730 731 732 733 734 735 736
    /*
     * Final check: if ciphersuite requires us to have a
     * certificate/key of a particular type:
     * - select the appropriate certificate if we have one, or
     * - try the next ciphersuite if we don't
     * This must be done last since we modify the key_cert list.
     */
    if( ssl_pick_cert( ssl, suite_info ) != 0 )
737
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
738
        MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: "
739
                            "no suitable certificate" ) );
740
        return( 0 );
741
    }
742 743 744 745 746 747
#endif

    *ciphersuite_info = suite_info;
    return( 0 );
}

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
748 749
#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
750
{
751
    int ret, got_common_suite;
752 753 754 755
    unsigned int i, j;
    size_t n;
    unsigned int ciph_len, sess_len, chal_len;
    unsigned char *buf, *p;
756
    const int *ciphersuites;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
757
    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
758

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
759
    MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) );
760

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
761 762
#if defined(MBEDTLS_SSL_RENEGOTIATION)
    if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
763
    {
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
764
        MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) );
765

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
766
        if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
767 768
            return( ret );

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
769
        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
770
    }
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
771
#endif /* MBEDTLS_SSL_RENEGOTIATION */
772