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