ssl_client2.c 55.5 KB
Newer Older
1 2 3
/*
 *  SSL client with certificate authentication
 *
4
 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5
 *  SPDX-License-Identifier: Apache-2.0
6
 *
7 8 9
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
10
 *
11
 *  http://www.apache.org/licenses/LICENSE-2.0
12
 *
13 14 15 16 17
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
18
 *
19
 *  This file is part of mbed TLS (https://tls.mbed.org)
20 21
 */

22
#if !defined(MBEDTLS_CONFIG_FILE)
23
#include "mbedtls/config.h"
24
#else
25
#include MBEDTLS_CONFIG_FILE
26
#endif
27

28
#if defined(MBEDTLS_PLATFORM_C)
29
#include "mbedtls/platform.h"
30
#else
Rich Evans's avatar
Rich Evans committed
31
#include <stdio.h>
32 33 34
#include <stdlib.h>
#define mbedtls_time       time
#define mbedtls_time_t     time_t
35 36 37
#define mbedtls_printf     printf
#define mbedtls_fprintf    fprintf
#define mbedtls_snprintf   snprintf
38 39
#endif

40 41
#if !defined(MBEDTLS_ENTROPY_C) || \
    !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
42
    !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
43 44 45 46
int main( void )
{
    mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
           "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
47
           "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
48 49 50 51
    return( 0 );
}
#else

52
#include "mbedtls/net_sockets.h"
53 54 55 56 57 58 59
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
60
#include "mbedtls/timing.h"
61

Rich Evans's avatar
Rich Evans committed
62 63 64
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
65

66
#define DFL_SERVER_NAME         "localhost"
67
#define DFL_SERVER_ADDR         NULL
68
#define DFL_SERVER_PORT         "4433"
69
#define DFL_REQUEST_PAGE        "/"
70
#define DFL_REQUEST_SIZE        -1
71
#define DFL_DEBUG_LEVEL         0
72
#define DFL_NBIO                0
73
#define DFL_READ_TIMEOUT        0
74
#define DFL_MAX_RESEND          0
75
#define DFL_CA_FILE             ""
76
#define DFL_CA_PATH             ""
Paul Bakker's avatar
Paul Bakker committed
77 78
#define DFL_CRT_FILE            ""
#define DFL_KEY_FILE            ""
79 80
#define DFL_PSK                 ""
#define DFL_PSK_IDENTITY        "Client_identity"
81
#define DFL_ECJPAKE_PW          NULL
82
#define DFL_FORCE_CIPHER        0
83
#define DFL_RENEGOTIATION       MBEDTLS_SSL_RENEGOTIATION_DISABLED
84
#define DFL_ALLOW_LEGACY        -2
85
#define DFL_RENEGOTIATE         0
86
#define DFL_EXCHANGES           1
87
#define DFL_MIN_VERSION         -1
88
#define DFL_MAX_VERSION         -1
89
#define DFL_ARC4                -1
90
#define DFL_AUTH_MODE           -1
91
#define DFL_MFL_CODE            MBEDTLS_SSL_MAX_FRAG_LEN_NONE
92
#define DFL_TRUNC_HMAC          -1
93
#define DFL_RECSPLIT            -1
94
#define DFL_DHMLEN              -1
95
#define DFL_RECONNECT           0
96
#define DFL_RECO_DELAY          0
97
#define DFL_RECONNECT_HARD      0
98
#define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
99
#define DFL_ALPN_STRING         NULL
100
#define DFL_TRANSPORT           MBEDTLS_SSL_TRANSPORT_STREAM
101 102
#define DFL_HS_TO_MIN           0
#define DFL_HS_TO_MAX           0
103
#define DFL_FALLBACK            -1
104
#define DFL_EXTENDED_MS         -1
105
#define DFL_ETM                 -1
106

107 108
#define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
#define GET_REQUEST_END "\r\n\r\n"
109

110 111
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_FS_IO)
112
#define USAGE_IO \
113 114 115 116 117 118
    "    ca_file=%%s          The single file containing the top-level CA(s) you fully trust\n" \
    "                        default: \"\" (pre-loaded)\n" \
    "    ca_path=%%s          The path containing the top-level CA(s) you fully trust\n" \
    "                        default: \"\" (pre-loaded) (overrides ca_file)\n" \
    "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
    "                        default: \"\" (pre-loaded)\n" \
119 120 121
    "    key_file=%%s         default: \"\" (pre-loaded)\n"
#else
#define USAGE_IO \
122 123
    "    No file operations available (MBEDTLS_FS_IO not defined)\n"
#endif /* MBEDTLS_FS_IO */
124 125
#else
#define USAGE_IO ""
126
#endif /* MBEDTLS_X509_CRT_PARSE_C */
127

128
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
129 130 131 132 133
#define USAGE_PSK                                                   \
    "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
    "    psk_identity=%%s     default: \"Client_identity\"\n"
#else
#define USAGE_PSK ""
134
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
135

136
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
137 138 139 140
#define USAGE_TICKETS                                       \
    "    tickets=%%d          default: 1 (enabled)\n"
#else
#define USAGE_TICKETS ""
141
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
142

143
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
144
#define USAGE_TRUNC_HMAC                                    \
145
    "    trunc_hmac=%%d       default: library default\n"
146 147
#else
#define USAGE_TRUNC_HMAC ""
148
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
149

150
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
151 152 153 154 155
#define USAGE_MAX_FRAG_LEN                                      \
    "    max_frag_len=%%d     default: 16384 (tls default)\n"   \
    "                        options: 512, 1024, 2048, 4096\n"
#else
#define USAGE_MAX_FRAG_LEN ""
156
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
157

158
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
159
#define USAGE_RECSPLIT \
160
    "    recsplit=0/1        default: (library default: on)\n"
161 162 163 164
#else
#define USAGE_RECSPLIT
#endif

165 166 167 168 169 170 171
#if defined(MBEDTLS_DHM_C)
#define USAGE_DHMLEN \
    "    dhmlen=%%d           default: (library default: 1024 bits)\n"
#else
#define USAGE_DHMLEN
#endif

172
#if defined(MBEDTLS_SSL_ALPN)
173 174 175 176 177
#define USAGE_ALPN \
    "    alpn=%%s             default: \"\" (disabled)\n"   \
    "                        example: spdy/1,http/1.1\n"
#else
#define USAGE_ALPN ""
178
#endif /* MBEDTLS_SSL_ALPN */
179

180
#if defined(MBEDTLS_SSL_PROTO_DTLS)
181 182 183 184 185 186 187 188
#define USAGE_DTLS \
    "    dtls=%%d             default: 0 (TLS)\n"                           \
    "    hs_timeout=%%d-%%d    default: (library default: 1000-60000)\n"    \
    "                        range of DTLS handshake timeouts in millisecs\n"
#else
#define USAGE_DTLS ""
#endif

189
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
190 191 192 193 194 195
#define USAGE_FALLBACK \
    "    fallback=0/1        default: (library default: off)\n"
#else
#define USAGE_FALLBACK ""
#endif

196
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
197 198 199 200 201 202
#define USAGE_EMS \
    "    extended_ms=0/1     default: (library default: on)\n"
#else
#define USAGE_EMS ""
#endif

203
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
204 205 206 207 208 209
#define USAGE_ETM \
    "    etm=0/1             default: (library default: on)\n"
#else
#define USAGE_ETM ""
#endif

210
#if defined(MBEDTLS_SSL_RENEGOTIATION)
211 212 213 214 215 216 217
#define USAGE_RENEGO \
    "    renegotiation=%%d    default: 0 (disabled)\n"      \
    "    renegotiate=%%d      default: 0 (disabled)\n"
#else
#define USAGE_RENEGO ""
#endif

218 219 220 221 222 223 224
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#define USAGE_ECJPAKE \
    "    ecjpake_pw=%%s       default: none (disabled)\n"
#else
#define USAGE_ECJPAKE ""
#endif

225
#define USAGE \
Paul Bakker's avatar
Paul Bakker committed
226 227 228
    "\n usage: ssl_client2 param=<>...\n"                   \
    "\n acceptable parameters:\n"                           \
    "    server_name=%%s      default: localhost\n"         \
229
    "    server_addr=%%s      default: given by name\n"     \
Paul Bakker's avatar
Paul Bakker committed
230
    "    server_port=%%d      default: 4433\n"              \
231
    "    request_page=%%s     default: \".\"\n"             \
232 233
    "    request_size=%%d     default: about 34 (basic request)\n" \
    "                        (minimum: 0, max: 16384)\n" \
Paul Bakker's avatar
Paul Bakker committed
234
    "    debug_level=%%d      default: 0 (disabled)\n"      \
235 236
    "    nbio=%%d             default: 0 (blocking I/O)\n"  \
    "                        options: 1 (non-blocking), 2 (added delays)\n" \
237
    "    read_timeout=%%d     default: 0 ms (no timeout)\n"    \
238
    "    max_resend=%%d       default: 0 (no resend on timeout)\n" \
239
    "\n"                                                    \
240 241
    USAGE_DTLS                                              \
    "\n"                                                    \
242
    "    auth_mode=%%s        default: (library default: none)\n"      \
243
    "                        options: none, optional, required\n" \
244
    USAGE_IO                                                \
245 246
    "\n"                                                    \
    USAGE_PSK                                               \
247
    USAGE_ECJPAKE                                           \
248
    "\n"                                                    \
249
    "    allow_legacy=%%d     default: (library default: no)\n"      \
250
    USAGE_RENEGO                                            \
251
    "    exchanges=%%d        default: 1\n"                 \
252
    "    reconnect=%%d        default: 0 (disabled)\n"      \
253
    "    reco_delay=%%d       default: 0 seconds\n"         \
254
    "    reconnect_hard=%%d   default: 0 (disabled)\n"      \
255
    USAGE_TICKETS                                           \
256 257
    USAGE_MAX_FRAG_LEN                                      \
    USAGE_TRUNC_HMAC                                        \
258
    USAGE_ALPN                                              \
259
    USAGE_FALLBACK                                          \
260
    USAGE_EMS                                               \
261
    USAGE_ETM                                               \
262
    USAGE_RECSPLIT                                          \
263
    USAGE_DHMLEN                                            \
264
    "\n"                                                    \
265
    "    arc4=%%d             default: (library default: 0)\n" \
266 267
    "    min_version=%%s      default: (library default: tls1)\n"       \
    "    max_version=%%s      default: (library default: tls1_2)\n"     \
268
    "    force_version=%%s    default: \"\" (none)\n"       \
269
    "                        options: ssl3, tls1, tls1_1, tls1_2, dtls1, dtls1_2\n" \
270
    "\n"                                                    \
271 272
    "    force_ciphersuite=<name>    default: all enabled\n"\
    " acceptable ciphersuite names:\n"
273

Rich Evans's avatar
Rich Evans committed
274 275 276 277 278 279 280
/*
 * global options
 */
struct options
{
    const char *server_name;    /* hostname of the server (client only)     */
    const char *server_addr;    /* address of the server (client only)      */
281
    const char *server_port;    /* port on which the ssl service runs       */
Rich Evans's avatar
Rich Evans committed
282 283
    int debug_level;            /* level of debugging                       */
    int nbio;                   /* should I/O be blocking?                  */
284
    uint32_t read_timeout;      /* timeout on mbedtls_ssl_read() in milliseconds    */
285
    int max_resend;             /* DTLS times to resend on read timeout     */
Rich Evans's avatar
Rich Evans committed
286 287 288 289 290 291 292 293
    const char *request_page;   /* page on server to request                */
    int request_size;           /* pad request with header to requested size */
    const char *ca_file;        /* the file with the CA certificate(s)      */
    const char *ca_path;        /* the path with the CA certificate(s) reside */
    const char *crt_file;       /* the file with the client certificate     */
    const char *key_file;       /* the file with the client key             */
    const char *psk;            /* the pre-shared key                       */
    const char *psk_identity;   /* the pre-shared key identity              */
294
    const char *ecjpake_pw;     /* the EC J-PAKE password                   */
Rich Evans's avatar
Rich Evans committed
295 296 297 298 299 300 301 302 303 304 305 306 307
    int force_ciphersuite[2];   /* protocol/ciphersuite to use, or all      */
    int renegotiation;          /* enable / disable renegotiation           */
    int allow_legacy;           /* allow legacy renegotiation               */
    int renegotiate;            /* attempt renegotiation?                   */
    int renego_delay;           /* delay before enforcing renegotiation     */
    int exchanges;              /* number of data exchanges                 */
    int min_version;            /* minimum protocol version accepted        */
    int max_version;            /* maximum protocol version accepted        */
    int arc4;                   /* flag for arc4 suites support             */
    int auth_mode;              /* verify mode for connection               */
    unsigned char mfl_code;     /* code for maximum fragment length         */
    int trunc_hmac;             /* negotiate truncated hmac or not          */
    int recsplit;               /* enable record splitting?                 */
308
    int dhmlen;                 /* minimum DHM params len in bits           */
Rich Evans's avatar
Rich Evans committed
309 310
    int reconnect;              /* attempt to resume session                */
    int reco_delay;             /* delay in seconds before resuming session */
311
    int reconnect_hard;         /* unexpectedly reconnect from the same port */
Rich Evans's avatar
Rich Evans committed
312 313
    int tickets;                /* enable / disable session tickets         */
    const char *alpn_string;    /* ALPN supported protocols                 */
314 315 316
    int transport;              /* TLS or DTLS?                             */
    uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
    uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
Rich Evans's avatar
Rich Evans committed
317 318 319 320 321
    int fallback;               /* is this a fallback connection?           */
    int extended_ms;            /* negotiate extended master secret?        */
    int etm;                    /* negotiate encrypt then mac?              */
} opt;

322 323 324
static void my_debug( void *ctx, int level,
                      const char *file, int line,
                      const char *str )
Rich Evans's avatar
Rich Evans committed
325
{
326
    const char *p, *basename;
Rich Evans's avatar
Rich Evans committed
327

328 329 330 331 332 333
    /* Extract basename from file */
    for( p = basename = file; *p != '\0'; p++ )
        if( *p == '/' || *p == '\\' )
            basename = p + 1;

    mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str );
Rich Evans's avatar
Rich Evans committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
    fflush(  (FILE *) ctx  );
}

/*
 * Test recv/send functions that make sure each try returns
 * WANT_READ/WANT_WRITE at least once before sucesseding
 */
static int my_recv( void *ctx, unsigned char *buf, size_t len )
{
    static int first_try = 1;
    int ret;

    if( first_try )
    {
        first_try = 0;
349
        return( MBEDTLS_ERR_SSL_WANT_READ );
Rich Evans's avatar
Rich Evans committed
350 351
    }

352
    ret = mbedtls_net_recv( ctx, buf, len );
353
    if( ret != MBEDTLS_ERR_SSL_WANT_READ )
Rich Evans's avatar
Rich Evans committed
354 355 356 357 358 359 360 361 362 363 364 365
        first_try = 1; /* Next call will be a new operation */
    return( ret );
}

static int my_send( void *ctx, const unsigned char *buf, size_t len )
{
    static int first_try = 1;
    int ret;

    if( first_try )
    {
        first_try = 0;
366
        return( MBEDTLS_ERR_SSL_WANT_WRITE );
Rich Evans's avatar
Rich Evans committed
367 368
    }

369
    ret = mbedtls_net_send( ctx, buf, len );
370
    if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Rich Evans's avatar
Rich Evans committed
371 372 373 374
        first_try = 1; /* Next call will be a new operation */
    return( ret );
}

375
#if defined(MBEDTLS_X509_CRT_PARSE_C)
Rich Evans's avatar
Rich Evans committed
376 377 378
/*
 * Enabled if debug_level > 1 in code below
 */
379
static int my_verify( void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags )
Rich Evans's avatar
Rich Evans committed
380 381 382 383
{
    char buf[1024];
    ((void) data);

384 385 386
    mbedtls_printf( "\nVerify requested for (Depth %d):\n", depth );
    mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
    mbedtls_printf( "%s", buf );
Rich Evans's avatar
Rich Evans committed
387 388

    if ( ( *flags ) == 0 )
389
        mbedtls_printf( "  This certificate has no flags\n" );
390 391 392 393 394
    else
    {
        mbedtls_x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
        mbedtls_printf( "%s\n", buf );
    }
Rich Evans's avatar
Rich Evans committed
395 396 397

    return( 0 );
}
398
#endif /* MBEDTLS_X509_CRT_PARSE_C */
Rich Evans's avatar
Rich Evans committed
399

400
int main( int argc, char *argv[] )
401
{
402 403
    int ret = 0, len, tail_len, i, written, frags, retry_left;
    mbedtls_net_context server_fd;
404 405 406
    unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
    unsigned char psk[MBEDTLS_PSK_MAX_LEN];
407
    size_t psk_len = 0;
408
#endif
409
#if defined(MBEDTLS_SSL_ALPN)
410
    const char *alpn_list[10];
411
#endif
412
    const char *pers = "ssl_client2";
413

414 415 416
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_ssl_context ssl;
417
    mbedtls_ssl_config conf;
418
    mbedtls_ssl_session saved_session;
419
#if defined(MBEDTLS_TIMING_C)
420
    mbedtls_timing_delay_context timer;
421
#endif
422
#if defined(MBEDTLS_X509_CRT_PARSE_C)
423
    uint32_t flags;
424 425 426
    mbedtls_x509_crt cacert;
    mbedtls_x509_crt clicert;
    mbedtls_pk_context pkey;
427
#endif
428
    char *p, *q;
429
    const int *list;
430

431 432 433
    /*
     * Make sure memory references are valid.
     */
434
    mbedtls_net_init( &server_fd );
435
    mbedtls_ssl_init( &ssl );
436
    mbedtls_ssl_config_init( &conf );
437
    memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
438
    mbedtls_ctr_drbg_init( &ctr_drbg );
439 440 441 442
#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt_init( &cacert );
    mbedtls_x509_crt_init( &clicert );
    mbedtls_pk_init( &pkey );
443
#endif
444
#if defined(MBEDTLS_SSL_ALPN)
445
    memset( (void * ) alpn_list, 0, sizeof( alpn_list ) );
446
#endif
447

448 449 450
    if( argc == 0 )
    {
    usage:
451 452 453
        if( ret == 0 )
            ret = 1;

454
        mbedtls_printf( USAGE );
455

456
        list = mbedtls_ssl_list_ciphersuites();
457 458
        while( *list )
        {
459
            mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name( *list ) );
460 461 462
            list++;
            if( !*list )
                break;
463
            mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name( *list ) );
464 465
            list++;
        }
466
        mbedtls_printf("\n");
467 468 469 470
        goto exit;
    }

    opt.server_name         = DFL_SERVER_NAME;
471
    opt.server_addr         = DFL_SERVER_ADDR;
472 473
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
474
    opt.nbio                = DFL_NBIO;
475
    opt.read_timeout        = DFL_READ_TIMEOUT;
476
    opt.max_resend          = DFL_MAX_RESEND;
477
    opt.request_page        = DFL_REQUEST_PAGE;
478
    opt.request_size        = DFL_REQUEST_SIZE;
479
    opt.ca_file             = DFL_CA_FILE;
480
    opt.ca_path             = DFL_CA_PATH;
Paul Bakker's avatar
Paul Bakker committed
481 482
    opt.crt_file            = DFL_CRT_FILE;
    opt.key_file            = DFL_KEY_FILE;
483 484
    opt.psk                 = DFL_PSK;
    opt.psk_identity        = DFL_PSK_IDENTITY;
485
    opt.ecjpake_pw          = DFL_ECJPAKE_PW;
486
    opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
487 488
    opt.renegotiation       = DFL_RENEGOTIATION;
    opt.allow_legacy        = DFL_ALLOW_LEGACY;
489
    opt.renegotiate         = DFL_RENEGOTIATE;
490
    opt.exchanges           = DFL_EXCHANGES;
491 492
    opt.min_version         = DFL_MIN_VERSION;
    opt.max_version         = DFL_MAX_VERSION;
493
    opt.arc4                = DFL_ARC4;
494
    opt.auth_mode           = DFL_AUTH_MODE;
495
    opt.mfl_code            = DFL_MFL_CODE;
496
    opt.trunc_hmac          = DFL_TRUNC_HMAC;
497
    opt.recsplit            = DFL_RECSPLIT;
498
    opt.dhmlen              = DFL_DHMLEN;
499
    opt.reconnect           = DFL_RECONNECT;
500
    opt.reco_delay          = DFL_RECO_DELAY;
501
    opt.reconnect_hard      = DFL_RECONNECT_HARD;
502
    opt.tickets             = DFL_TICKETS;
503
    opt.alpn_string         = DFL_ALPN_STRING;
504 505 506
    opt.transport           = DFL_TRANSPORT;
    opt.hs_to_min           = DFL_HS_TO_MIN;
    opt.hs_to_max           = DFL_HS_TO_MAX;
507
    opt.fallback            = DFL_FALLBACK;
508
    opt.extended_ms         = DFL_EXTENDED_MS;
509
    opt.etm                 = DFL_ETM;
510 511 512 513 514 515 516 517 518 519

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "server_name" ) == 0 )
            opt.server_name = q;
520 521
        else if( strcmp( p, "server_addr" ) == 0 )
            opt.server_addr = q;
522
        else if( strcmp( p, "server_port" ) == 0 )
523
            opt.server_port = q;
524 525 526 527
        else if( strcmp( p, "dtls" ) == 0 )
        {
            int t = atoi( q );
            if( t == 0 )
528
                opt.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
529
            else if( t == 1 )
530
                opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
531 532 533
            else
                goto usage;
        }
534 535 536 537 538 539
        else if( strcmp( p, "debug_level" ) == 0 )
        {
            opt.debug_level = atoi( q );
            if( opt.debug_level < 0 || opt.debug_level > 65535 )
                goto usage;
        }
540 541 542 543 544 545
        else if( strcmp( p, "nbio" ) == 0 )
        {
            opt.nbio = atoi( q );
            if( opt.nbio < 0 || opt.nbio > 2 )
                goto usage;
        }
546 547
        else if( strcmp( p, "read_timeout" ) == 0 )
            opt.read_timeout = atoi( q );
548 549 550 551 552 553
        else if( strcmp( p, "max_resend" ) == 0 )
        {
            opt.max_resend = atoi( q );
            if( opt.max_resend < 0 )
                goto usage;
        }
554 555
        else if( strcmp( p, "request_page" ) == 0 )
            opt.request_page = q;
556 557 558
        else if( strcmp( p, "request_size" ) == 0 )
        {
            opt.request_size = atoi( q );
559
            if( opt.request_size < 0 || opt.request_size > MBEDTLS_SSL_MAX_CONTENT_LEN )
560 561
                goto usage;
        }
562 563
        else if( strcmp( p, "ca_file" ) == 0 )
            opt.ca_file = q;
564 565
        else if( strcmp( p, "ca_path" ) == 0 )
            opt.ca_path = q;
Paul Bakker's avatar
Paul Bakker committed
566 567 568 569
        else if( strcmp( p, "crt_file" ) == 0 )
            opt.crt_file = q;
        else if( strcmp( p, "key_file" ) == 0 )
            opt.key_file = q;
570 571 572 573
        else if( strcmp( p, "psk" ) == 0 )
            opt.psk = q;
        else if( strcmp( p, "psk_identity" ) == 0 )
            opt.psk_identity = q;
574 575
        else if( strcmp( p, "ecjpake_pw" ) == 0 )
            opt.ecjpake_pw = q;
576 577
        else if( strcmp( p, "force_ciphersuite" ) == 0 )
        {
578
            opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
579

580
            if( opt.force_ciphersuite[0] == 0 )
581 582
            {
                ret = 2;
583
                goto usage;
584
            }
585 586
            opt.force_ciphersuite[1] = 0;
        }
587 588
        else if( strcmp( p, "renegotiation" ) == 0 )
        {
589 590
            opt.renegotiation = (atoi( q )) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED :
                                              MBEDTLS_SSL_RENEGOTIATION_DISABLED;
591 592 593
        }
        else if( strcmp( p, "allow_legacy" ) == 0 )
        {
594 595
            switch( atoi( q ) )
            {
596 597 598
                case -1: opt.allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE; break;
                case 0:  opt.allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; break;
                case 1:  opt.allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION; break;
599 600
                default: goto usage;
            }
601
        }
602 603 604 605 606 607
        else if( strcmp( p, "renegotiate" ) == 0 )
        {
            opt.renegotiate = atoi( q );
            if( opt.renegotiate < 0 || opt.renegotiate > 1 )
                goto usage;
        }
608 609 610 611 612 613
        else if( strcmp( p, "exchanges" ) == 0 )
        {
            opt.exchanges = atoi( q );
            if( opt.exchanges < 1 )
                goto usage;
        }
614 615 616
        else if( strcmp( p, "reconnect" ) == 0 )
        {
            opt.reconnect = atoi( q );
617
            if( opt.reconnect < 0 || opt.reconnect > 2 )
618 619
                goto usage;
        }
620 621 622 623 624 625
        else if( strcmp( p, "reco_delay" ) == 0 )
        {
            opt.reco_delay = atoi( q );
            if( opt.reco_delay < 0 )
                goto usage;
        }
626 627 628 629 630 631
        else if( strcmp( p, "reconnect_hard" ) == 0 )
        {
            opt.reconnect_hard = atoi( q );
            if( opt.reconnect_hard < 0 || opt.reconnect_hard > 1 )
                goto usage;
        }
632 633 634 635 636 637
        else if( strcmp( p, "tickets" ) == 0 )
        {
            opt.tickets = atoi( q );
            if( opt.tickets < 0 || opt.tickets > 2 )
                goto usage;
        }
638 639 640 641
        else if( strcmp( p, "alpn" ) == 0 )
        {
            opt.alpn_string = q;
        }
642 643 644 645
        else if( strcmp( p, "fallback" ) == 0 )
        {
            switch( atoi( q ) )
            {
646 647
                case 0: opt.fallback = MBEDTLS_SSL_IS_NOT_FALLBACK; break;
                case 1: opt.fallback = MBEDTLS_SSL_IS_FALLBACK; break;
648 649 650
                default: goto usage;
            }
        }
651 652 653 654
        else if( strcmp( p, "extended_ms" ) == 0 )
        {
            switch( atoi( q ) )
            {
655 656
                case 0: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED; break;
                case 1: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; break;
657 658 659
                default: goto usage;
            }
        }
660 661 662 663
        else if( strcmp( p, "etm" ) == 0 )
        {
            switch( atoi( q ) )
            {
664 665
                case 0: opt.etm = MBEDTLS_SSL_ETM_DISABLED; break;
                case 1: opt.etm = MBEDTLS_SSL_ETM_ENABLED; break;
666 667 668
                default: goto usage;
            }
        }
669 670 671
        else if( strcmp( p, "min_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
672
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
673
            else if( strcmp( q, "tls1" ) == 0 )
674
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
675 676
            else if( strcmp( q, "tls1_1" ) == 0 ||
                     strcmp( q, "dtls1" ) == 0 )
677
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
678 679
            else if( strcmp( q, "tls1_2" ) == 0 ||
                     strcmp( q, "dtls1_2" ) == 0 )
680
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
681 682 683 684 685 686
            else
                goto usage;
        }
        else if( strcmp( p, "max_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
687
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
688
            else if( strcmp( q, "tls1" ) == 0 )
689
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
690 691
            else if( strcmp( q, "tls1_1" ) == 0 ||
                     strcmp( q, "dtls1" ) == 0 )
692
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
693 694
            else if( strcmp( q, "tls1_2" ) == 0 ||
                     strcmp( q, "dtls1_2" ) == 0 )
695
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
696 697 698
            else
                goto usage;
        }
699 700 701 702
        else if( strcmp( p, "arc4" ) == 0 )
        {
            switch( atoi( q ) )
            {
703 704
                case 0:     opt.arc4 = MBEDTLS_SSL_ARC4_DISABLED;   break;
                case 1:     opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;    break;
705 706 707
                default:    goto usage;
            }
        }
708 709 710 711
        else if( strcmp( p, "force_version" ) == 0 )
        {
            if( strcmp( q, "ssl3" ) == 0 )
            {
712 713
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
714 715 716
            }
            else if( strcmp( q, "tls1" ) == 0 )
            {
717 718
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
719
            }
720
            else if( strcmp( q, "tls1_1" ) == 0 )
721
            {
722 723
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
724
            }
725 726
            else if( strcmp( q, "tls1_2" ) == 0 )
            {
727 728
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
729 730 731
            }
            else if( strcmp( q, "dtls1" ) == 0 )
            {
732 733 734
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
                opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
735 736
            }
            else if( strcmp( q, "dtls1_2" ) == 0 )
737
            {
738 739 740
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
                opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
                opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
741 742 743 744
            }
            else
                goto usage;
        }
745 746 747
        else if( strcmp( p, "auth_mode" ) == 0 )
        {
            if( strcmp( q, "none" ) == 0 )
748
                opt.auth_mode = MBEDTLS_SSL_VERIFY_NONE;
749
            else if( strcmp( q, "optional" ) == 0 )
750
                opt.auth_mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
751
            else if( strcmp( q, "required" ) == 0 )
752
                opt.auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED;
753 754 755
            else
                goto usage;
        }
756 757 758
        else if( strcmp( p, "max_frag_len" ) == 0 )
        {
            if( strcmp( q, "512" ) == 0 )
759
                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512;
760
            else if( strcmp( q, "1024" ) == 0 )
761
                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_1024;
762
            else if( strcmp( q, "2048" ) == 0 )
763
                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_2048;
764
            else if( strcmp( q, "4096" ) == 0 )
765
                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_4096;
766 767 768
            else
                goto usage;
        }
769 770
        else if( strcmp( p, "trunc_hmac" ) == 0 )
        {
771 772
            switch( atoi( q ) )
            {
773 774
                case 0: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED; break;
                case 1: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; break;
775 776
                default: goto usage;
            }
777
        }
778 779 780 781 782 783 784 785 786 787
        else if( strcmp( p, "hs_timeout" ) == 0 )
        {
            if( ( p = strchr( q, '-' ) ) == NULL )
                goto usage;
            *p++ = '\0';
            opt.hs_to_min = atoi( q );
            opt.hs_to_max = atoi( p );
            if( opt.hs_to_min == 0 || opt.hs_to_max < opt.hs_to_min )
                goto usage;
        }
788 789 790 791 792 793
        else if( strcmp( p, "recsplit" ) == 0 )
        {
            opt.recsplit = atoi( q );
            if( opt.recsplit < 0 || opt.recsplit > 1 )
                goto usage;
        }
794 795 796 797 798 799
        else if( strcmp( p, "dhmlen" ) == 0 )
        {
            opt.dhmlen = atoi( q );
            if( opt.dhmlen < 0 )
                goto usage;
        }
800 801 802
        else
            goto usage;
    }
803

804 805
#if defined(MBEDTLS_DEBUG_C)
    mbedtls_debug_set_threshold( opt.debug_level );
806 807
#endif

808 809
    if( opt.force_ciphersuite[0] > 0 )
    {
810 811
        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
812

813 814 815
        if( opt.max_version != -1 &&
            ciphersuite_info->min_minor_ver > opt.max_version )
        {
816
            mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
817 818 819 820
            ret = 2;
            goto usage;
        }
        if( opt.min_version != -1 &&
821 822
            ciphersuite_info->max_minor_ver < opt.min_version )
        {
823
            mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
824 825 826
            ret = 2;
            goto usage;
        }
827 828 829 830 831 832

        /* If the server selects a version that's not supported by
         * this suite, then there will be no common ciphersuite... */
        if( opt.max_version == -1 ||
            opt.max_version > ciphersuite_info->max_minor_ver )
        {
833
            opt.max_version = ciphersuite_info->max_minor_ver;
834
        }
835
        if( opt.min_version < ciphersuite_info->min_minor_ver )
836
        {
837
            opt.min_version = ciphersuite_info->min_minor_ver;
838
            /* DTLS starts with TLS 1.1 */
839 840 841
            if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
                opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
                opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
842
        }
843 844

        /* Enable RC4 if needed and not explicitly disabled */
845
        if( ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
846
        {
847
            if( opt.arc4 == MBEDTLS_SSL_ARC4_DISABLED )
848
            {
849
                mbedtls_printf("forced RC4 ciphersuite with RC4 disabled\n");
850 851 852 853
                ret = 2;
                goto usage;
            }

854
            opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
855
        }
856 857
    }

858
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
859 860 861 862 863 864 865 866 867 868
    /*
     * Unhexify the pre-shared key if any is given
     */
    if( strlen( opt.psk ) )
    {
        unsigned char c;
        size_t j;

        if( strlen( opt.psk ) % 2 != 0 )
        {
869
            mbedtls_printf("pre-shared key not valid hex\n");
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885
            goto exit;
        }

        psk_len = strlen( opt.psk ) / 2;

        for( j = 0; j < strlen( opt.psk ); j += 2 )
        {
            c = opt.psk[j];
            if( c >= '0' && c <= '9' )
                c -= '0';
            else if( c >= 'a' && c <= 'f' )
                c -= 'a' - 10;
            else if( c >= 'A' && c <= 'F' )
                c -= 'A' - 10;
            else
            {
886
                mbedtls_printf("pre-shared key not valid hex\n");
887 888 889 890 891 892 893 894 895 896 897 898 899
                goto exit;
            }
            psk[ j / 2 ] = c << 4;

            c = opt.psk[j + 1];
            if( c >= '0' && c <= '9' )
                c -= '0';
            else if( c >= 'a' && c <= 'f' )
                c -= 'a' - 10;
            else if( c >= 'A' && c <= 'F' )
                c -= 'A' - 10;
            else
            {
900
                mbedtls_printf("pre-shared key not valid hex\n");
901 902 903 904 905
                goto exit;
            }
            psk[ j / 2 ] |= c;
        }
    }
906
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
907

908
#if defined(MBEDTLS_SSL_ALPN)
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
    if( opt.alpn_string != NULL )
    {
        p = (char *) opt.alpn_string;
        i = 0;

        /* Leave room for a final NULL in alpn_list */
        while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
        {
            alpn_list[i++] = p;

            /* Terminate the current string and move on to next one */
            while( *p != ',' && *p != '\0' )
                p++;
            if( *p == ',' )
                *p++ = '\0';
        }
    }
926
#endif /* MBEDTLS_SSL_ALPN */
927

928 929 930
    /*
     * 0. Initialize the RNG and the session data
     */
931
    mbedtls_printf( "\n  . Seeding the random number generator..." );
932 933
    fflush( stdout );

934
    mbedtls_entropy_init( &entropy );
935
    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
936 937
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
938
    {
939
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
940 941 942
        goto exit;
    }

943
    mbedtls_printf( " ok\n" );
944

945
#if defined(MBEDTLS_X509_CRT_PARSE_C)
946 947 948
    /*
     * 1.1. Load the trusted CA
     */
949
    mbedtls_printf( "  . Loading the CA root certificate ..." );
950 951
    fflush( stdout );

952
#if defined(MBEDTLS_FS_IO)
953
    if( strlen( opt.ca_path ) )
954 955 956
        if( strcmp( opt.ca_path, "none" ) == 0 )
            ret = 0;
        else
957
            ret = mbedtls_x509_crt_parse_path( &cacert, opt.ca_path );
958
    else if( strlen( opt.ca_file ) )
959 960 961
        if( strcmp( opt.ca_file, "none" ) == 0 )
            ret = 0;
        else
962
            ret = mbedtls_x509_crt_parse_file( &cacert, opt.ca_file );
963
    else
964
#endif
965 966
#if defined(MBEDTLS_CERTS_C)
        for( i = 0; mbedtls_test_cas[i] != NULL; i++ )
967
        {
968 969 970
            ret = mbedtls_x509_crt_parse( &cacert,
                                  (const unsigned char *) mbedtls_test_cas[i],
                                  mbedtls_test_cas_len[i] );
971 972 973
            if( ret != 0 )
                break;
        }
974 975 976
#else
    {
        ret = 1;
977
        mbedtls_printf("MBEDTLS_CERTS_C not defined.");
978 979
    }
#endif
980
    if( ret < 0 )
981
    {
982
        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
983 984 985
        goto exit;
    }

986
    mbedtls_printf( " ok (%d skipped)\n", ret );
987 988 989 990 991 992

    /*
     * 1.2. Load own certificate and private key
     *
     * (can be skipped if client authentication is not required)
     */
993
    mbedtls_printf( "  . Loading the client cert. and key..." );
994 995
    fflush( stdout );

996
#if defined(MBEDTLS_FS_IO)
Paul Bakker's avatar
Paul Bakker committed
997
    if( strlen( opt.crt_file ) )
998 999 1000
        if( strcmp( opt.crt_file, "none" ) == 0 )
            ret = 0;
        else
1001
            ret = mbedtls_x509_crt_parse_file( &clicert, opt.crt_file );
1002
    else
1003
#endif
1004 1005 1006
#if defined(MBEDTLS_CERTS_C)
        ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
                mbedtls_test_cli_crt_len );
1007 1008 1009
#else
    {
        ret = 1;
1010
        mbedtls_printf("MBEDTLS_CERTS_C not defined.");
1011 1012
    }
#endif
1013 1014
    if( ret != 0 )
    {
1015
        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
1016 1017 1018
        goto exit;
    }

1019
#if defined(MBEDTLS_FS_IO)
Paul Bakker's avatar
Paul Bakker committed
1020
    if( strlen( opt.key_file ) )
1021 1022 1023
        if( strcmp( opt.key_file, "none" ) == 0 )
            ret = 0;
        else
1024
            ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" );
Paul Bakker's avatar
Paul Bakker committed
1025
    else
1026
#endif
1027 1028 1029
#if defined(MBEDTLS_CERTS_C)
        ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key,
                mbedtls_test_cli_key_len, NULL, 0 );
1030 1031 1032
#else
    {
        ret = 1;
1033
        mbedtls_printf("MBEDTLS_CERTS_C not defined.");
1034 1035
    }
#endif
1036 1037
    if( ret != 0 )
    {
1038
        mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n", -ret );
1039 1040 1041
        goto exit;
    }

1042 1043
    mbedtls_printf( " ok\n" );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
1044 1045 1046 1047

    /*
     * 2. Start the connection
     */
1048 1049 1050
    if( opt.server_addr == NULL)
        opt.server_addr = opt.server_name;

1051
    mbedtls_printf( "  . Connecting to %s/%s/%s...",
1052
            opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ? "tcp" : "udp",
1053
            opt.server_addr, opt.server_port );
1054 1055
    fflush( stdout );

1056 1057 1058
    if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port,
                             opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
                             MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) != 0 )
1059
    {
1060
        mbedtls_printf( " failed\n  ! mbedtls_net_connect returned -0x%x\n\n", -ret );
1061 1062 1063
        goto exit;
    }

1064
    if( opt.nbio > 0 )
1065
        ret = mbedtls_net_set_nonblock( &server_fd );
1066
    else
1067
        ret = mbedtls_net_set_block( &server_fd );
1068 1069
    if( ret != 0 )
    {
1070
        mbedtls_printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n", -ret );
1071 1072 1073
        goto exit;
    }

1074
    mbedtls_printf( " ok\n" );
1075 1076 1077 1078

    /*
     * 3. Setup stuff
     */
1079
    mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
1080 1081
    fflush( stdout );

1082 1083
    if( ( ret = mbedtls_ssl_config_defaults( &conf,
                    MBEDTLS_SSL_IS_CLIENT,
1084 1085
                    opt.transport,
                    MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
1086 1087 1088 1089 1090
    {
        mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
        goto exit;
    }

1091
#if defined(MBEDTLS_X509_CRT_PARSE_C)
1092
    if( opt.debug_level > 0 )
1093
        mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
1094
#endif
1095

1096
    if( opt.auth_mode != DFL_AUTH_MODE )
1097
        mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
1098

1099
#if defined(MBEDTLS_SSL_PROTO_DTLS)
1100
    if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
1101
        mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
1102
#endif /* MBEDTLS_SSL_PROTO_DTLS */
1103

1104
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1105
    if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
1106
    {
1107
        mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
1108 1109
        goto exit;
    }
1110
#endif
1111

1112
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1113
    if( opt.trunc_hmac != DFL_TRUNC_HMAC )
1114
        mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
1115
#endif