1 /*
2  *  SSL client with certificate authentication
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: Apache-2.0
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  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
31 #include <stdio.h>
32 #include <stdlib.h>
33 #define mbedtls_time       time
34 #define mbedtls_time_t     time_t
35 #define mbedtls_printf     printf
36 #define mbedtls_fprintf    fprintf
37 #define mbedtls_snprintf   snprintf
38 #endif
39 
40 #if !defined(MBEDTLS_ENTROPY_C) || \
41     !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
42     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
main(void)43 int main( void )
44 {
45     mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
46            "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     return( 0 );
49 }
50 #else
51 
52 #include "mbedtls/net_sockets.h"
53 #include "mbedtls/ssl.h"
54 #include "mbedtls/entropy.h"
55 #include "mbedtls/ctr_drbg.h"
56 #include "mbedtls/certs.h"
57 #include "mbedtls/x509.h"
58 #include "mbedtls/error.h"
59 #include "mbedtls/debug.h"
60 #include "mbedtls/timing.h"
61 
62 #include <stdio.h>
63 #include <stdlib.h>
64 #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             ""
77 #define DFL_CRT_FILE            ""
78 #define DFL_KEY_FILE            ""
79 #define DFL_PSK                 ""
80 #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 #define DFL_HS_TO_MIN           0
102 #define DFL_HS_TO_MAX           0
103 #define DFL_FALLBACK            -1
104 #define DFL_EXTENDED_MS         -1
105 #define DFL_ETM                 -1
106 
107 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
108 #define GET_REQUEST_END "\r\n\r\n"
109 
110 #if defined(MBEDTLS_X509_CRT_PARSE_C)
111 #if defined(MBEDTLS_FS_IO)
112 #define USAGE_IO \
113     "    ca_file=%%s          The single file containing the top-level CA(s) you fully trust\n" \
114     "                        default: \"\" (pre-loaded)\n" \
115     "    ca_path=%%s          The path containing the top-level CA(s) you fully trust\n" \
116     "                        default: \"\" (pre-loaded) (overrides ca_file)\n" \
117     "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
118     "                        default: \"\" (pre-loaded)\n" \
119     "    key_file=%%s         default: \"\" (pre-loaded)\n"
120 #else
121 #define USAGE_IO \
122     "    No file operations available (MBEDTLS_FS_IO not defined)\n"
123 #endif /* MBEDTLS_FS_IO */
124 #else
125 #define USAGE_IO ""
126 #endif /* MBEDTLS_X509_CRT_PARSE_C */
127 
128 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
129 #define USAGE_PSK                                                   \
130     "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
131     "    psk_identity=%%s     default: \"Client_identity\"\n"
132 #else
133 #define USAGE_PSK ""
134 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
135 
136 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
137 #define USAGE_TICKETS                                       \
138     "    tickets=%%d          default: 1 (enabled)\n"
139 #else
140 #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 #else
147 #define USAGE_TRUNC_HMAC ""
148 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
149 
150 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
151 #define USAGE_MAX_FRAG_LEN                                      \
152     "    max_frag_len=%%d     default: 16384 (tls default)\n"   \
153     "                        options: 512, 1024, 2048, 4096\n"
154 #else
155 #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 #else
162 #define USAGE_RECSPLIT
163 #endif
164 
165 #if defined(MBEDTLS_DHM_C)
166 #define USAGE_DHMLEN \
167     "    dhmlen=%%d           default: (library default: 1024 bits)\n"
168 #else
169 #define USAGE_DHMLEN
170 #endif
171 
172 #if defined(MBEDTLS_SSL_ALPN)
173 #define USAGE_ALPN \
174     "    alpn=%%s             default: \"\" (disabled)\n"   \
175     "                        example: spdy/1,http/1.1\n"
176 #else
177 #define USAGE_ALPN ""
178 #endif /* MBEDTLS_SSL_ALPN */
179 
180 #if defined(MBEDTLS_SSL_PROTO_DTLS)
181 #define USAGE_DTLS \
182     "    dtls=%%d             default: 0 (TLS)\n"                           \
183     "    hs_timeout=%%d-%%d    default: (library default: 1000-60000)\n"    \
184     "                        range of DTLS handshake timeouts in millisecs\n"
185 #else
186 #define USAGE_DTLS ""
187 #endif
188 
189 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
190 #define USAGE_FALLBACK \
191     "    fallback=0/1        default: (library default: off)\n"
192 #else
193 #define USAGE_FALLBACK ""
194 #endif
195 
196 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
197 #define USAGE_EMS \
198     "    extended_ms=0/1     default: (library default: on)\n"
199 #else
200 #define USAGE_EMS ""
201 #endif
202 
203 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
204 #define USAGE_ETM \
205     "    etm=0/1             default: (library default: on)\n"
206 #else
207 #define USAGE_ETM ""
208 #endif
209 
210 #if defined(MBEDTLS_SSL_RENEGOTIATION)
211 #define USAGE_RENEGO \
212     "    renegotiation=%%d    default: 0 (disabled)\n"      \
213     "    renegotiate=%%d      default: 0 (disabled)\n"
214 #else
215 #define USAGE_RENEGO ""
216 #endif
217 
218 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
219 #define USAGE_ECJPAKE \
220     "    ecjpake_pw=%%s       default: none (disabled)\n"
221 #else
222 #define USAGE_ECJPAKE ""
223 #endif
224 
225 #define USAGE \
226     "\n usage: ssl_client2 param=<>...\n"                   \
227     "\n acceptable parameters:\n"                           \
228     "    server_name=%%s      default: localhost\n"         \
229     "    server_addr=%%s      default: given by name\n"     \
230     "    server_port=%%d      default: 4433\n"              \
231     "    request_page=%%s     default: \".\"\n"             \
232     "    request_size=%%d     default: about 34 (basic request)\n" \
233     "                        (minimum: 0, max: 16384)\n" \
234     "    debug_level=%%d      default: 0 (disabled)\n"      \
235     "    nbio=%%d             default: 0 (blocking I/O)\n"  \
236     "                        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     USAGE_DTLS                                              \
241     "\n"                                                    \
242     "    auth_mode=%%s        default: (library default: none)\n"      \
243     "                        options: none, optional, required\n" \
244     USAGE_IO                                                \
245     "\n"                                                    \
246     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     USAGE_MAX_FRAG_LEN                                      \
257     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     "    min_version=%%s      default: (library default: tls1)\n"       \
267     "    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     "    force_ciphersuite=<name>    default: all enabled\n"\
272     " acceptable ciphersuite names:\n"
273 
274 /*
275  * global options
276  */
277 struct options
278 {
279     const char *server_name;    /* hostname of the server (client only)     */
280     const char *server_addr;    /* address of the server (client only)      */
281     const char *server_port;    /* port on which the ssl service runs       */
282     int debug_level;            /* level of debugging                       */
283     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     */
286     const char *request_page;   /* page on server to request                */
287     int request_size;           /* pad request with header to requested size */
288     const char *ca_file;        /* the file with the CA certificate(s)      */
289     const char *ca_path;        /* the path with the CA certificate(s) reside */
290     const char *crt_file;       /* the file with the client certificate     */
291     const char *key_file;       /* the file with the client key             */
292     const char *psk;            /* the pre-shared key                       */
293     const char *psk_identity;   /* the pre-shared key identity              */
294     const char *ecjpake_pw;     /* the EC J-PAKE password                   */
295     int force_ciphersuite[2];   /* protocol/ciphersuite to use, or all      */
296     int renegotiation;          /* enable / disable renegotiation           */
297     int allow_legacy;           /* allow legacy renegotiation               */
298     int renegotiate;            /* attempt renegotiation?                   */
299     int renego_delay;           /* delay before enforcing renegotiation     */
300     int exchanges;              /* number of data exchanges                 */
301     int min_version;            /* minimum protocol version accepted        */
302     int max_version;            /* maximum protocol version accepted        */
303     int arc4;                   /* flag for arc4 suites support             */
304     int auth_mode;              /* verify mode for connection               */
305     unsigned char mfl_code;     /* code for maximum fragment length         */
306     int trunc_hmac;             /* negotiate truncated hmac or not          */
307     int recsplit;               /* enable record splitting?                 */
308     int dhmlen;                 /* minimum DHM params len in bits           */
309     int reconnect;              /* attempt to resume session                */
310     int reco_delay;             /* delay in seconds before resuming session */
311     int reconnect_hard;         /* unexpectedly reconnect from the same port */
312     int tickets;                /* enable / disable session tickets         */
313     const char *alpn_string;    /* ALPN supported protocols                 */
314     int transport;              /* TLS or DTLS?                             */
315     uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
316     uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
317     int fallback;               /* is this a fallback connection?           */
318     int extended_ms;            /* negotiate extended master secret?        */
319     int etm;                    /* negotiate encrypt then mac?              */
320 } opt;
321 
my_debug(void * ctx,int level,const char * file,int line,const char * str)322 static void my_debug( void *ctx, int level,
323                       const char *file, int line,
324                       const char *str )
325 {
326     const char *p, *basename;
327 
328     /* Extract basename from file */
329     for( p = basename = file; *p != '\0'; p++ )
330         if( *p == '/' || *p == '\\' )
331             basename = p + 1;
332 
333     mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str );
334     fflush(  (FILE *) ctx  );
335 }
336 
337 /*
338  * Test recv/send functions that make sure each try returns
339  * WANT_READ/WANT_WRITE at least once before sucesseding
340  */
my_recv(void * ctx,unsigned char * buf,size_t len)341 static int my_recv( void *ctx, unsigned char *buf, size_t len )
342 {
343     static int first_try = 1;
344     int ret;
345 
346     if( first_try )
347     {
348         first_try = 0;
349         return( MBEDTLS_ERR_SSL_WANT_READ );
350     }
351 
352     ret = mbedtls_net_recv( ctx, buf, len );
353     if( ret != MBEDTLS_ERR_SSL_WANT_READ )
354         first_try = 1; /* Next call will be a new operation */
355     return( ret );
356 }
357 
my_send(void * ctx,const unsigned char * buf,size_t len)358 static int my_send( void *ctx, const unsigned char *buf, size_t len )
359 {
360     static int first_try = 1;
361     int ret;
362 
363     if( first_try )
364     {
365         first_try = 0;
366         return( MBEDTLS_ERR_SSL_WANT_WRITE );
367     }
368 
369     ret = mbedtls_net_send( ctx, buf, len );
370     if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
371         first_try = 1; /* Next call will be a new operation */
372     return( ret );
373 }
374 
375 #if defined(MBEDTLS_X509_CRT_PARSE_C)
376 /*
377  * Enabled if debug_level > 1 in code below
378  */
my_verify(void * data,mbedtls_x509_crt * crt,int depth,uint32_t * flags)379 static int my_verify( void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags )
380 {
381     char buf[1024];
382     ((void) data);
383 
384     mbedtls_printf( "\nVerify requested for (Depth %d):\n", depth );
385     mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
386     mbedtls_printf( "%s", buf );
387 
388     if ( ( *flags ) == 0 )
389         mbedtls_printf( "  This certificate has no flags\n" );
390     else
391     {
392         mbedtls_x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
393         mbedtls_printf( "%s\n", buf );
394     }
395 
396     return( 0 );
397 }
398 #endif /* MBEDTLS_X509_CRT_PARSE_C */
399 
main(int argc,char * argv[])400 int main( int argc, char *argv[] )
401 {
402     int ret = 0, len, tail_len, i, written, frags, retry_left;
403     mbedtls_net_context server_fd;
404     unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];
405 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
406     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     mbedtls_entropy_context entropy;
415     mbedtls_ctr_drbg_context ctr_drbg;
416     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     mbedtls_x509_crt cacert;
425     mbedtls_x509_crt clicert;
426     mbedtls_pk_context pkey;
427 #endif
428     char *p, *q;
429     const int *list;
430 
431     /*
432      * Make sure memory references are valid.
433      */
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 #if defined(MBEDTLS_X509_CRT_PARSE_C)
440     mbedtls_x509_crt_init( &cacert );
441     mbedtls_x509_crt_init( &clicert );
442     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     if( argc == 0 )
449     {
450     usage:
451         if( ret == 0 )
452             ret = 1;
453 
454         mbedtls_printf( USAGE );
455 
456         list = mbedtls_ssl_list_ciphersuites();
457         while( *list )
458         {
459             mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name( *list ) );
460             list++;
461             if( !*list )
462                 break;
463             mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name( *list ) );
464             list++;
465         }
466         mbedtls_printf("\n");
467         goto exit;
468     }
469 
470     opt.server_name         = DFL_SERVER_NAME;
471     opt.server_addr         = DFL_SERVER_ADDR;
472     opt.server_port         = DFL_SERVER_PORT;
473     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;
481     opt.crt_file            = DFL_CRT_FILE;
482     opt.key_file            = DFL_KEY_FILE;
483     opt.psk                 = DFL_PSK;
484     opt.psk_identity        = DFL_PSK_IDENTITY;
485     opt.ecjpake_pw          = DFL_ECJPAKE_PW;
486     opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
487     opt.renegotiation       = DFL_RENEGOTIATION;
488     opt.allow_legacy        = DFL_ALLOW_LEGACY;
489     opt.renegotiate         = DFL_RENEGOTIATE;
490     opt.exchanges           = DFL_EXCHANGES;
491     opt.min_version         = DFL_MIN_VERSION;
492     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     opt.transport           = DFL_TRANSPORT;
505     opt.hs_to_min           = DFL_HS_TO_MIN;
506     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     for( i = 1; i < argc; i++ )
512     {
513         p = argv[i];
514         if( ( q = strchr( p, '=' ) ) == NULL )
515             goto usage;
516         *q++ = '\0';
517 
518         if( strcmp( p, "server_name" ) == 0 )
519             opt.server_name = q;
520         else if( strcmp( p, "server_addr" ) == 0 )
521             opt.server_addr = q;
522         else if( strcmp( p, "server_port" ) == 0 )
523             opt.server_port = q;
524         else if( strcmp( p, "dtls" ) == 0 )
525         {
526             int t = atoi( q );
527             if( t == 0 )
528                 opt.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
529             else if( t == 1 )
530                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
531             else
532                 goto usage;
533         }
534         else if( strcmp( p, "debug_level" ) == 0 )
535         {
536             opt.debug_level = atoi( q );
537             if( opt.debug_level < 0 || opt.debug_level > 65535 )
538                 goto usage;
539         }
540         else if( strcmp( p, "nbio" ) == 0 )
541         {
542             opt.nbio = atoi( q );
543             if( opt.nbio < 0 || opt.nbio > 2 )
544                 goto usage;
545         }
546         else if( strcmp( p, "read_timeout" ) == 0 )
547             opt.read_timeout = atoi( q );
548         else if( strcmp( p, "max_resend" ) == 0 )
549         {
550             opt.max_resend = atoi( q );
551             if( opt.max_resend < 0 )
552                 goto usage;
553         }
554         else if( strcmp( p, "request_page" ) == 0 )
555             opt.request_page = q;
556         else if( strcmp( p, "request_size" ) == 0 )
557         {
558             opt.request_size = atoi( q );
559             if( opt.request_size < 0 || opt.request_size > MBEDTLS_SSL_MAX_CONTENT_LEN )
560                 goto usage;
561         }
562         else if( strcmp( p, "ca_file" ) == 0 )
563             opt.ca_file = q;
564         else if( strcmp( p, "ca_path" ) == 0 )
565             opt.ca_path = q;
566         else if( strcmp( p, "crt_file" ) == 0 )
567             opt.crt_file = q;
568         else if( strcmp( p, "key_file" ) == 0 )
569             opt.key_file = q;
570         else if( strcmp( p, "psk" ) == 0 )
571             opt.psk = q;
572         else if( strcmp( p, "psk_identity" ) == 0 )
573             opt.psk_identity = q;
574         else if( strcmp( p, "ecjpake_pw" ) == 0 )
575             opt.ecjpake_pw = q;
576         else if( strcmp( p, "force_ciphersuite" ) == 0 )
577         {
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             opt.force_ciphersuite[1] = 0;
586         }
587         else if( strcmp( p, "renegotiation" ) == 0 )
588         {
589             opt.renegotiation = (atoi( q )) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED :
590                                               MBEDTLS_SSL_RENEGOTIATION_DISABLED;
591         }
592         else if( strcmp( p, "allow_legacy" ) == 0 )
593         {
594             switch( atoi( q ) )
595             {
596                 case -1: opt.allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE; break;
597                 case 0:  opt.allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; break;
598                 case 1:  opt.allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION; break;
599                 default: goto usage;
600             }
601         }
602         else if( strcmp( p, "renegotiate" ) == 0 )
603         {
604             opt.renegotiate = atoi( q );
605             if( opt.renegotiate < 0 || opt.renegotiate > 1 )
606                 goto usage;
607         }
608         else if( strcmp( p, "exchanges" ) == 0 )
609         {
610             opt.exchanges = atoi( q );
611             if( opt.exchanges < 1 )
612                 goto usage;
613         }
614         else if( strcmp( p, "reconnect" ) == 0 )
615         {
616             opt.reconnect = atoi( q );
617             if( opt.reconnect < 0 || opt.reconnect > 2 )
618                 goto usage;
619         }
620         else if( strcmp( p, "reco_delay" ) == 0 )
621         {
622             opt.reco_delay = atoi( q );
623             if( opt.reco_delay < 0 )
624                 goto usage;
625         }
626         else if( strcmp( p, "reconnect_hard" ) == 0 )
627         {
628             opt.reconnect_hard = atoi( q );
629             if( opt.reconnect_hard < 0 || opt.reconnect_hard > 1 )
630                 goto usage;
631         }
632         else if( strcmp( p, "tickets" ) == 0 )
633         {
634             opt.tickets = atoi( q );
635             if( opt.tickets < 0 || opt.tickets > 2 )
636                 goto usage;
637         }
638         else if( strcmp( p, "alpn" ) == 0 )
639         {
640             opt.alpn_string = q;
641         }
642         else if( strcmp( p, "fallback" ) == 0 )
643         {
644             switch( atoi( q ) )
645             {
646                 case 0: opt.fallback = MBEDTLS_SSL_IS_NOT_FALLBACK; break;
647                 case 1: opt.fallback = MBEDTLS_SSL_IS_FALLBACK; break;
648                 default: goto usage;
649             }
650         }
651         else if( strcmp( p, "extended_ms" ) == 0 )
652         {
653             switch( atoi( q ) )
654             {
655                 case 0: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED; break;
656                 case 1: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; break;
657                 default: goto usage;
658             }
659         }
660         else if( strcmp( p, "etm" ) == 0 )
661         {
662             switch( atoi( q ) )
663             {
664                 case 0: opt.etm = MBEDTLS_SSL_ETM_DISABLED; break;
665                 case 1: opt.etm = MBEDTLS_SSL_ETM_ENABLED; break;
666                 default: goto usage;
667             }
668         }
669         else if( strcmp( p, "min_version" ) == 0 )
670         {
671             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             else if( strcmp( q, "tls1_1" ) == 0 ||
676                      strcmp( q, "dtls1" ) == 0 )
677                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
678             else if( strcmp( q, "tls1_2" ) == 0 ||
679                      strcmp( q, "dtls1_2" ) == 0 )
680                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
681             else
682                 goto usage;
683         }
684         else if( strcmp( p, "max_version" ) == 0 )
685         {
686             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             else if( strcmp( q, "tls1_1" ) == 0 ||
691                      strcmp( q, "dtls1" ) == 0 )
692                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
693             else if( strcmp( q, "tls1_2" ) == 0 ||
694                      strcmp( q, "dtls1_2" ) == 0 )
695                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
696             else
697                 goto usage;
698         }
699         else if( strcmp( p, "arc4" ) == 0 )
700         {
701             switch( atoi( q ) )
702             {
703                 case 0:     opt.arc4 = MBEDTLS_SSL_ARC4_DISABLED;   break;
704                 case 1:     opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;    break;
705                 default:    goto usage;
706             }
707         }
708         else if( strcmp( p, "force_version" ) == 0 )
709         {
710             if( strcmp( q, "ssl3" ) == 0 )
711             {
712                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
713                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
714             }
715             else if( strcmp( q, "tls1" ) == 0 )
716             {
717                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
718                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
719             }
720             else if( strcmp( q, "tls1_1" ) == 0 )
721             {
722                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
723                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
724             }
725             else if( strcmp( q, "tls1_2" ) == 0 )
726             {
727                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
728                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
729             }
730             else if( strcmp( q, "dtls1" ) == 0 )
731             {
732                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
733                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
734                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
735             }
736             else if( strcmp( q, "dtls1_2" ) == 0 )
737             {
738                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
739                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
740                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
741             }
742             else
743                 goto usage;
744         }
745         else if( strcmp( p, "auth_mode" ) == 0 )
746         {
747             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             else
754                 goto usage;
755         }
756         else if( strcmp( p, "max_frag_len" ) == 0 )
757         {
758             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             else
767                 goto usage;
768         }
769         else if( strcmp( p, "trunc_hmac" ) == 0 )
770         {
771             switch( atoi( q ) )
772             {
773                 case 0: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED; break;
774                 case 1: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; break;
775                 default: goto usage;
776             }
777         }
778         else if( strcmp( p, "hs_timeout" ) == 0 )
779         {
780             if( ( p = strchr( q, '-' ) ) == NULL )
781                 goto usage;
782             *p++ = '\0';
783             opt.hs_to_min = atoi( q );
784             opt.hs_to_max = atoi( p );
785             if( opt.hs_to_min == 0 || opt.hs_to_max < opt.hs_to_min )
786                 goto usage;
787         }
788         else if( strcmp( p, "recsplit" ) == 0 )
789         {
790             opt.recsplit = atoi( q );
791             if( opt.recsplit < 0 || opt.recsplit > 1 )
792                 goto usage;
793         }
794         else if( strcmp( p, "dhmlen" ) == 0 )
795         {
796             opt.dhmlen = atoi( q );
797             if( opt.dhmlen < 0 )
798                 goto usage;
799         }
800         else
801             goto usage;
802     }
803 
804 #if defined(MBEDTLS_DEBUG_C)
805     mbedtls_debug_set_threshold( opt.debug_level );
806 #endif
807 
808     if( opt.force_ciphersuite[0] > 0 )
809     {
810         const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
811         ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
812 
813         if( opt.max_version != -1 &&
814             ciphersuite_info->min_minor_ver > opt.max_version )
815         {
816             mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
817             ret = 2;
818             goto usage;
819         }
820         if( opt.min_version != -1 &&
821             ciphersuite_info->max_minor_ver < opt.min_version )
822         {
823             mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
824             ret = 2;
825             goto usage;
826         }
827 
828         /* If the server selects a version that's not supported by
829          * this suite, then there will be no common ciphersuite... */
830         if( opt.max_version == -1 ||
831             opt.max_version > ciphersuite_info->max_minor_ver )
832         {
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             if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
840                 opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
841                 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                 ret = 2;
851                 goto usage;
852             }
853 
854             opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
855         }
856     }
857 
858 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
859     /*
860      * Unhexify the pre-shared key if any is given
861      */
862     if( strlen( opt.psk ) )
863     {
864         unsigned char c;
865         size_t j;
866 
867         if( strlen( opt.psk ) % 2 != 0 )
868         {
869             mbedtls_printf("pre-shared key not valid hex\n");
870             goto exit;
871         }
872 
873         psk_len = strlen( opt.psk ) / 2;
874 
875         for( j = 0; j < strlen( opt.psk ); j += 2 )
876         {
877             c = opt.psk[j];
878             if( c >= '0' && c <= '9' )
879                 c -= '0';
880             else if( c >= 'a' && c <= 'f' )
881                 c -= 'a' - 10;
882             else if( c >= 'A' && c <= 'F' )
883                 c -= 'A' - 10;
884             else
885             {
886                 mbedtls_printf("pre-shared key not valid hex\n");
887                 goto exit;
888             }
889             psk[ j / 2 ] = c << 4;
890 
891             c = opt.psk[j + 1];
892             if( c >= '0' && c <= '9' )
893                 c -= '0';
894             else if( c >= 'a' && c <= 'f' )
895                 c -= 'a' - 10;
896             else if( c >= 'A' && c <= 'F' )
897                 c -= 'A' - 10;
898             else
899             {
900                 mbedtls_printf("pre-shared key not valid hex\n");
901                 goto exit;
902             }
903             psk[ j / 2 ] |= c;
904         }
905     }
906 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
907 
908 #if defined(MBEDTLS_SSL_ALPN)
909     if( opt.alpn_string != NULL )
910     {
911         p = (char *) opt.alpn_string;
912         i = 0;
913 
914         /* Leave room for a final NULL in alpn_list */
915         while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
916         {
917             alpn_list[i++] = p;
918 
919             /* Terminate the current string and move on to next one */
920             while( *p != ',' && *p != '\0' )
921                 p++;
922             if( *p == ',' )
923                 *p++ = '\0';
924         }
925     }
926 #endif /* MBEDTLS_SSL_ALPN */
927 
928     /*
929      * 0. Initialize the RNG and the session data
930      */
931     mbedtls_printf( "\n  . Seeding the random number generator..." );
932     fflush( stdout );
933 
934     mbedtls_entropy_init( &entropy );
935     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
936                                (const unsigned char *) pers,
937                                strlen( pers ) ) ) != 0 )
938     {
939         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
940         goto exit;
941     }
942 
943     mbedtls_printf( " ok\n" );
944 
945 #if defined(MBEDTLS_X509_CRT_PARSE_C)
946     /*
947      * 1.1. Load the trusted CA
948      */
949     mbedtls_printf( "  . Loading the CA root certificate ..." );
950     fflush( stdout );
951 
952 #if defined(MBEDTLS_FS_IO)
953     if( strlen( opt.ca_path ) )
954         if( strcmp( opt.ca_path, "none" ) == 0 )
955             ret = 0;
956         else
957             ret = mbedtls_x509_crt_parse_path( &cacert, opt.ca_path );
958     else if( strlen( opt.ca_file ) )
959         if( strcmp( opt.ca_file, "none" ) == 0 )
960             ret = 0;
961         else
962             ret = mbedtls_x509_crt_parse_file( &cacert, opt.ca_file );
963     else
964 #endif
965 #if defined(MBEDTLS_CERTS_C)
966         for( i = 0; mbedtls_test_cas[i] != NULL; i++ )
967         {
968             ret = mbedtls_x509_crt_parse( &cacert,
969                                   (const unsigned char *) mbedtls_test_cas[i],
970                                   mbedtls_test_cas_len[i] );
971             if( ret != 0 )
972                 break;
973         }
974 #else
975     {
976         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         goto exit;
984     }
985 
986     mbedtls_printf( " ok (%d skipped)\n", ret );
987 
988     /*
989      * 1.2. Load own certificate and private key
990      *
991      * (can be skipped if client authentication is not required)
992      */
993     mbedtls_printf( "  . Loading the client cert. and key..." );
994     fflush( stdout );
995 
996 #if defined(MBEDTLS_FS_IO)
997     if( strlen( opt.crt_file ) )
998         if( strcmp( opt.crt_file, "none" ) == 0 )
999             ret = 0;
1000         else
1001             ret = mbedtls_x509_crt_parse_file( &clicert, opt.crt_file );
1002     else
1003 #endif
1004 #if defined(MBEDTLS_CERTS_C)
1005         ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
1006                 mbedtls_test_cli_crt_len );
1007 #else
1008     {
1009         ret = 1;
1010         mbedtls_printf("MBEDTLS_CERTS_C not defined.");
1011     }
1012 #endif
1013     if( ret != 0 )
1014     {
1015         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
1016         goto exit;
1017     }
1018 
1019 #if defined(MBEDTLS_FS_IO)
1020     if( strlen( opt.key_file ) )
1021         if( strcmp( opt.key_file, "none" ) == 0 )
1022             ret = 0;
1023         else
1024             ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" );
1025     else
1026 #endif
1027 #if defined(MBEDTLS_CERTS_C)
1028         ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key,
1029                 mbedtls_test_cli_key_len, NULL, 0 );
1030 #else
1031     {
1032         ret = 1;
1033         mbedtls_printf("MBEDTLS_CERTS_C not defined.");
1034     }
1035 #endif
1036     if( ret != 0 )
1037     {
1038         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n", -ret );
1039         goto exit;
1040     }
1041 
1042     mbedtls_printf( " ok\n" );
1043 #endif /* MBEDTLS_X509_CRT_PARSE_C */
1044 
1045     /*
1046      * 2. Start the connection
1047      */
1048     if( opt.server_addr == NULL)
1049         opt.server_addr = opt.server_name;
1050 
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     fflush( stdout );
1055 
1056     if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port,
1057                              opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
1058                              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         goto exit;
1062     }
1063 
1064     if( opt.nbio > 0 )
1065         ret = mbedtls_net_set_nonblock( &server_fd );
1066     else
1067         ret = mbedtls_net_set_block( &server_fd );
1068     if( ret != 0 )
1069     {
1070         mbedtls_printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n", -ret );
1071         goto exit;
1072     }
1073 
1074     mbedtls_printf( " ok\n" );
1075 
1076     /*
1077      * 3. Setup stuff
1078      */
1079     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
1080     fflush( stdout );
1081 
1082     if( ( ret = mbedtls_ssl_config_defaults( &conf,
1083                     MBEDTLS_SSL_IS_CLIENT,
1084                     opt.transport,
1085                     MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
1086     {
1087         mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
1088         goto exit;
1089     }
1090 
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         goto exit;
1109     }
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
1116 
1117 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1118     if( opt.extended_ms != DFL_EXTENDED_MS )
1119         mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
1120 #endif
1121 
1122 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1123     if( opt.etm != DFL_ETM )
1124         mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
1125 #endif
1126 
1127 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
1128     if( opt.recsplit != DFL_RECSPLIT )
1129         mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit
1130                                     ? MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED
1131                                     : MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED );
1132 #endif
1133 
1134 #if defined(MBEDTLS_DHM_C)
1135     if( opt.dhmlen != DFL_DHMLEN )
1136         mbedtls_ssl_conf_dhm_min_bitlen( &conf, opt.dhmlen );
1137 #endif
1138 
1139 #if defined(MBEDTLS_SSL_ALPN)
1140     if( opt.alpn_string != NULL )
1141         if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
1142         {
1143             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n", ret );
1144             goto exit;
1145         }
1146 #endif
1147 
1148     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
1149     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
1150 
1151     mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
1152 
1153 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
1154     mbedtls_ssl_conf_session_tickets( &conf, opt.tickets );
1155 #endif
1156 
1157     if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
1158         mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
1159 
1160 #if defined(MBEDTLS_ARC4_C)
1161     if( opt.arc4 != DFL_ARC4 )
1162         mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 );
1163 #endif
1164 
1165     if( opt.allow_legacy != DFL_ALLOW_LEGACY )
1166         mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy );
1167 #if defined(MBEDTLS_SSL_RENEGOTIATION)
1168     mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation );
1169 #endif
1170 
1171 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1172     if( strcmp( opt.ca_path, "none" ) != 0 &&
1173         strcmp( opt.ca_file, "none" ) != 0 )
1174     {
1175         mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
1176     }
1177     if( strcmp( opt.crt_file, "none" ) != 0 &&
1178         strcmp( opt.key_file, "none" ) != 0 )
1179     {
1180         if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
1181         {
1182             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
1183             goto exit;
1184         }
1185     }
1186 #endif
1187 
1188 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1189     if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
1190                              (const unsigned char *) opt.psk_identity,
1191                              strlen( opt.psk_identity ) ) ) != 0 )
1192     {
1193         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_psk returned %d\n\n", ret );
1194         goto exit;
1195     }
1196 #endif
1197 
1198     if( opt.min_version != DFL_MIN_VERSION )
1199         mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
1200 
1201     if( opt.max_version != DFL_MAX_VERSION )
1202         mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
1203 
1204 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
1205     if( opt.fallback != DFL_FALLBACK )
1206         mbedtls_ssl_conf_fallback( &conf, opt.fallback );
1207 #endif
1208 
1209     if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
1210     {
1211         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
1212         goto exit;
1213     }
1214 
1215 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1216     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
1217     {
1218         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
1219         goto exit;
1220     }
1221 #endif
1222 
1223 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1224     if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
1225     {
1226         if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
1227                         (const unsigned char *) opt.ecjpake_pw,
1228                                         strlen( opt.ecjpake_pw ) ) ) != 0 )
1229         {
1230             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
1231             goto exit;
1232         }
1233     }
1234 #endif
1235 
1236     if( opt.nbio == 2 )
1237         mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
1238     else
1239         mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
1240                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
1241 
1242 #if defined(MBEDTLS_TIMING_C)
1243     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
1244                                             mbedtls_timing_get_delay );
1245 #endif
1246 
1247     mbedtls_printf( " ok\n" );
1248 
1249     /*
1250      * 4. Handshake
1251      */
1252     mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
1253     fflush( stdout );
1254 
1255     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
1256     {
1257         if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1258         {
1259             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n", -ret );
1260             if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
1261                 mbedtls_printf(
1262                     "    Unable to verify the server's certificate. "
1263                         "Either it is invalid,\n"
1264                     "    or you didn't set ca_file or ca_path "
1265                         "to an appropriate value.\n"
1266                     "    Alternatively, you may want to use "
1267                         "auth_mode=optional for testing purposes.\n" );
1268             mbedtls_printf( "\n" );
1269             goto exit;
1270         }
1271     }
1272 
1273     mbedtls_printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
1274             mbedtls_ssl_get_version( &ssl ), mbedtls_ssl_get_ciphersuite( &ssl ) );
1275 
1276     if( ( ret = mbedtls_ssl_get_record_expansion( &ssl ) ) >= 0 )
1277         mbedtls_printf( "    [ Record expansion is %d ]\n", ret );
1278     else
1279         mbedtls_printf( "    [ Record expansion is unknown (compression) ]\n" );
1280 
1281 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1282     mbedtls_printf( "    [ Maximum fragment length is %u ]\n",
1283                     (unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
1284 #endif
1285 
1286 #if defined(MBEDTLS_SSL_ALPN)
1287     if( opt.alpn_string != NULL )
1288     {
1289         const char *alp = mbedtls_ssl_get_alpn_protocol( &ssl );
1290         mbedtls_printf( "    [ Application Layer Protocol is %s ]\n",
1291                 alp ? alp : "(none)" );
1292     }
1293 #endif
1294 
1295     if( opt.reconnect != 0 )
1296     {
1297         mbedtls_printf("  . Saving session for reuse..." );
1298         fflush( stdout );
1299 
1300         if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
1301         {
1302             mbedtls_printf( " failed\n  ! mbedtls_ssl_get_session returned -0x%x\n\n", -ret );
1303             goto exit;
1304         }
1305 
1306         mbedtls_printf( " ok\n" );
1307     }
1308 
1309 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1310     /*
1311      * 5. Verify the server certificate
1312      */
1313     mbedtls_printf( "  . Verifying peer X.509 certificate..." );
1314 
1315     if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
1316     {
1317         char vrfy_buf[512];
1318 
1319         mbedtls_printf( " failed\n" );
1320 
1321         mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
1322 
1323         mbedtls_printf( "%s\n", vrfy_buf );
1324     }
1325     else
1326         mbedtls_printf( " ok\n" );
1327 
1328     if( mbedtls_ssl_get_peer_cert( &ssl ) != NULL )
1329     {
1330         mbedtls_printf( "  . Peer certificate information    ...\n" );
1331         mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
1332                        mbedtls_ssl_get_peer_cert( &ssl ) );
1333         mbedtls_printf( "%s\n", buf );
1334     }
1335 #endif /* MBEDTLS_X509_CRT_PARSE_C */
1336 
1337 #if defined(MBEDTLS_SSL_RENEGOTIATION)
1338     if( opt.renegotiate )
1339     {
1340         /*
1341          * Perform renegotiation (this must be done when the server is waiting
1342          * for input from our side).
1343          */
1344         mbedtls_printf( "  . Performing renegotiation..." );
1345         fflush( stdout );
1346         while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
1347         {
1348             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1349                 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1350             {
1351                 mbedtls_printf( " failed\n  ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
1352                 goto exit;
1353             }
1354         }
1355         mbedtls_printf( " ok\n" );
1356     }
1357 #endif /* MBEDTLS_SSL_RENEGOTIATION */
1358 
1359     /*
1360      * 6. Write the GET request
1361      */
1362     retry_left = opt.max_resend;
1363 send_request:
1364     mbedtls_printf( "  > Write to server:" );
1365     fflush( stdout );
1366 
1367     len = mbedtls_snprintf( (char *) buf, sizeof(buf) - 1, GET_REQUEST,
1368                     opt.request_page );
1369     tail_len = (int) strlen( GET_REQUEST_END );
1370 
1371     /* Add padding to GET request to reach opt.request_size in length */
1372     if( opt.request_size != DFL_REQUEST_SIZE &&
1373         len + tail_len < opt.request_size )
1374     {
1375         memset( buf + len, 'A', opt.request_size - len - tail_len );
1376         len += opt.request_size - len - tail_len;
1377     }
1378 
1379     strncpy( (char *) buf + len, GET_REQUEST_END, sizeof(buf) - len - 1 );
1380     len += tail_len;
1381 
1382     /* Truncate if request size is smaller than the "natural" size */
1383     if( opt.request_size != DFL_REQUEST_SIZE &&
1384         len > opt.request_size )
1385     {
1386         len = opt.request_size;
1387 
1388         /* Still end with \r\n unless that's really not possible */
1389         if( len >= 2 ) buf[len - 2] = '\r';
1390         if( len >= 1 ) buf[len - 1] = '\n';
1391     }
1392 
1393     if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
1394     {
1395         for( written = 0, frags = 0; written < len; written += ret, frags++ )
1396         {
1397             while( ( ret = mbedtls_ssl_write( &ssl, buf + written, len - written ) )
1398                            <= 0 )
1399             {
1400                 if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1401                     ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1402                 {
1403                     mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned -0x%x\n\n", -ret );
1404                     goto exit;
1405                 }
1406             }
1407         }
1408     }
1409     else /* Not stream, so datagram */
1410     {
1411         do ret = mbedtls_ssl_write( &ssl, buf, len );
1412         while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
1413                ret == MBEDTLS_ERR_SSL_WANT_WRITE );
1414 
1415         if( ret < 0 )
1416         {
1417             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
1418             goto exit;
1419         }
1420 
1421         frags = 1;
1422         written = ret;
1423     }
1424 
1425     buf[written] = '\0';
1426     mbedtls_printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );
1427 
1428     /*
1429      * 7. Read the HTTP response
1430      */
1431     mbedtls_printf( "  < Read from server:" );
1432     fflush( stdout );
1433 
1434     /*
1435      * TLS and DTLS need different reading styles (stream vs datagram)
1436      */
1437     if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
1438     {
1439         do
1440         {
1441             len = sizeof( buf ) - 1;
1442             memset( buf, 0, sizeof( buf ) );
1443             ret = mbedtls_ssl_read( &ssl, buf, len );
1444 
1445             if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
1446                 ret == MBEDTLS_ERR_SSL_WANT_WRITE )
1447                 continue;
1448 
1449             if( ret <= 0 )
1450             {
1451                 switch( ret )
1452                 {
1453                     case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
1454                         mbedtls_printf( " connection was closed gracefully\n" );
1455                         ret = 0;
1456                         goto close_notify;
1457 
1458                     case 0:
1459                     case MBEDTLS_ERR_NET_CONN_RESET:
1460                         mbedtls_printf( " connection was reset by peer\n" );
1461                         ret = 0;
1462                         goto reconnect;
1463 
1464                     default:
1465                         mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
1466                         goto exit;
1467                 }
1468             }
1469 
1470             len = ret;
1471             buf[len] = '\0';
1472             mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
1473 
1474             /* End of message should be detected according to the syntax of the
1475              * application protocol (eg HTTP), just use a dummy test here. */
1476             if( ret > 0 && buf[len-1] == '\n' )
1477             {
1478                 ret = 0;
1479                 break;
1480             }
1481         }
1482         while( 1 );
1483     }
1484     else /* Not stream, so datagram */
1485     {
1486         len = sizeof( buf ) - 1;
1487         memset( buf, 0, sizeof( buf ) );
1488 
1489         do ret = mbedtls_ssl_read( &ssl, buf, len );
1490         while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
1491                ret == MBEDTLS_ERR_SSL_WANT_WRITE );
1492 
1493         if( ret <= 0 )
1494         {
1495             switch( ret )
1496             {
1497                 case MBEDTLS_ERR_SSL_TIMEOUT:
1498                     mbedtls_printf( " timeout\n" );
1499                     if( retry_left-- > 0 )
1500                         goto send_request;
1501                     goto exit;
1502 
1503                 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
1504                     mbedtls_printf( " connection was closed gracefully\n" );
1505                     ret = 0;
1506                     goto close_notify;
1507 
1508                 default:
1509                     mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
1510                     goto exit;
1511             }
1512         }
1513 
1514         len = ret;
1515         buf[len] = '\0';
1516         mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
1517         ret = 0;
1518     }
1519 
1520     /*
1521      * 7b. Simulate hard reset and reconnect from same port?
1522      */
1523     if( opt.reconnect_hard != 0 )
1524     {
1525         opt.reconnect_hard = 0;
1526 
1527         mbedtls_printf( "  . Restarting connection from same port..." );
1528         fflush( stdout );
1529 
1530         if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
1531         {
1532             mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned -0x%x\n\n", -ret );
1533             goto exit;
1534         }
1535 
1536         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
1537         {
1538             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1539                 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1540             {
1541                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
1542                 goto exit;
1543             }
1544         }
1545 
1546         mbedtls_printf( " ok\n" );
1547 
1548         goto send_request;
1549     }
1550 
1551     /*
1552      * 7c. Continue doing data exchanges?
1553      */
1554     if( --opt.exchanges > 0 )
1555         goto send_request;
1556 
1557     /*
1558      * 8. Done, cleanly close the connection
1559      */
1560 close_notify:
1561     mbedtls_printf( "  . Closing the connection..." );
1562     fflush( stdout );
1563 
1564     /* No error checking, the connection might be closed already */
1565     do ret = mbedtls_ssl_close_notify( &ssl );
1566     while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
1567     ret = 0;
1568 
1569     mbedtls_printf( " done\n" );
1570 
1571     /*
1572      * 9. Reconnect?
1573      */
1574 reconnect:
1575     if( opt.reconnect != 0 )
1576     {
1577         --opt.reconnect;
1578 
1579         mbedtls_net_free( &server_fd );
1580 
1581 #if defined(MBEDTLS_TIMING_C)
1582         if( opt.reco_delay > 0 )
1583             mbedtls_net_usleep( 1000000 * opt.reco_delay );
1584 #endif
1585 
1586         mbedtls_printf( "  . Reconnecting with saved session..." );
1587 
1588         if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
1589         {
1590             mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned -0x%x\n\n", -ret );
1591             goto exit;
1592         }
1593 
1594         if( ( ret = mbedtls_ssl_set_session( &ssl, &saved_session ) ) != 0 )
1595         {
1596             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_session returned %d\n\n", ret );
1597             goto exit;
1598         }
1599 
1600         if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port,
1601                                  opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
1602                                  MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) != 0 )
1603         {
1604             mbedtls_printf( " failed\n  ! mbedtls_net_connect returned -0x%x\n\n", -ret );
1605             goto exit;
1606         }
1607 
1608         if( opt.nbio > 0 )
1609             ret = mbedtls_net_set_nonblock( &server_fd );
1610         else
1611             ret = mbedtls_net_set_block( &server_fd );
1612         if( ret != 0 )
1613         {
1614             mbedtls_printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n",
1615                     -ret );
1616             goto exit;
1617         }
1618 
1619         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
1620         {
1621             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1622                 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1623             {
1624                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
1625                 goto exit;
1626             }
1627         }
1628 
1629         mbedtls_printf( " ok\n" );
1630 
1631         goto send_request;
1632     }
1633 
1634     /*
1635      * Cleanup and exit
1636      */
1637 exit:
1638 #ifdef MBEDTLS_ERROR_C
1639     if( ret != 0 )
1640     {
1641         char error_buf[100];
1642         mbedtls_strerror( ret, error_buf, 100 );
1643         mbedtls_printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
1644     }
1645 #endif
1646 
1647     mbedtls_net_free( &server_fd );
1648 
1649 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1650     mbedtls_x509_crt_free( &clicert );
1651     mbedtls_x509_crt_free( &cacert );
1652     mbedtls_pk_free( &pkey );
1653 #endif
1654     mbedtls_ssl_session_free( &saved_session );
1655     mbedtls_ssl_free( &ssl );
1656     mbedtls_ssl_config_free( &conf );
1657     mbedtls_ctr_drbg_free( &ctr_drbg );
1658     mbedtls_entropy_free( &entropy );
1659 
1660 #if defined(_WIN32)
1661     mbedtls_printf( "  + Press Enter to exit this program.\n" );
1662     fflush( stdout ); getchar();
1663 #endif
1664 
1665     // Shell can not handle large exit numbers -> 1 for errors
1666     if( ret < 0 )
1667         ret = 1;
1668 
1669     return( ret );
1670 }
1671 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
1672           MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
1673           MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */
1674