• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  SSL client with certificate authentication
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  *
7  *  This file is provided under the Apache License 2.0, or the
8  *  GNU General Public License v2.0 or later.
9  *
10  *  **********
11  *  Apache License 2.0:
12  *
13  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14  *  not use this file except in compliance with the License.
15  *  You may obtain a copy of the License at
16  *
17  *  http://www.apache.org/licenses/LICENSE-2.0
18  *
19  *  Unless required by applicable law or agreed to in writing, software
20  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the License for the specific language governing permissions and
23  *  limitations under the License.
24  *
25  *  **********
26  *
27  *  **********
28  *  GNU General Public License v2.0 or later:
29  *
30  *  This program is free software; you can redistribute it and/or modify
31  *  it under the terms of the GNU General Public License as published by
32  *  the Free Software Foundation; either version 2 of the License, or
33  *  (at your option) any later version.
34  *
35  *  This program is distributed in the hope that it will be useful,
36  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  *  GNU General Public License for more details.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43  *
44  *  **********
45  */
46 
47 #if !defined(MBEDTLS_CONFIG_FILE)
48 #include "mbedtls/config.h"
49 #else
50 #include MBEDTLS_CONFIG_FILE
51 #endif
52 
53 #if defined(MBEDTLS_PLATFORM_C)
54 #include "mbedtls/platform.h"
55 #else
56 #include <stdio.h>
57 #include <stdlib.h>
58 #define mbedtls_time       time
59 #define mbedtls_time_t     time_t
60 #define mbedtls_printf     printf
61 #define mbedtls_fprintf    fprintf
62 #define mbedtls_snprintf   snprintf
63 #define mbedtls_exit            exit
64 #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
65 #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
66 #endif
67 
68 #if !defined(MBEDTLS_ENTROPY_C) || \
69     !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
70     !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
main(void)71 int main( void )
72 {
73     mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
74            "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
75            "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
76     mbedtls_exit( 0 );
77 }
78 #else
79 
80 #include "mbedtls/net_sockets.h"
81 #include "mbedtls/ssl.h"
82 #include "mbedtls/entropy.h"
83 #include "mbedtls/ctr_drbg.h"
84 #include "mbedtls/certs.h"
85 #include "mbedtls/x509.h"
86 #include "mbedtls/error.h"
87 #include "mbedtls/debug.h"
88 #include "mbedtls/timing.h"
89 
90 #include <stdio.h>
91 #include <stdlib.h>
92 #include <string.h>
93 
94 #define MAX_REQUEST_SIZE      20000
95 #define MAX_REQUEST_SIZE_STR "20000"
96 
97 #define DFL_SERVER_NAME         "localhost"
98 #define DFL_SERVER_ADDR         NULL
99 #define DFL_SERVER_PORT         "4433"
100 #define DFL_REQUEST_PAGE        "/"
101 #define DFL_REQUEST_SIZE        -1
102 #define DFL_DEBUG_LEVEL         0
103 #define DFL_NBIO                0
104 #define DFL_EVENT               0
105 #define DFL_READ_TIMEOUT        0
106 #define DFL_MAX_RESEND          0
107 #define DFL_CA_FILE             ""
108 #define DFL_CA_PATH             ""
109 #define DFL_CRT_FILE            ""
110 #define DFL_KEY_FILE            ""
111 #define DFL_PSK                 ""
112 #define DFL_PSK_IDENTITY        "Client_identity"
113 #define DFL_ECJPAKE_PW          NULL
114 #define DFL_EC_MAX_OPS          -1
115 #define DFL_FORCE_CIPHER        0
116 #define DFL_RENEGOTIATION       MBEDTLS_SSL_RENEGOTIATION_DISABLED
117 #define DFL_ALLOW_LEGACY        -2
118 #define DFL_RENEGOTIATE         0
119 #define DFL_EXCHANGES           1
120 #define DFL_MIN_VERSION         -1
121 #define DFL_MAX_VERSION         -1
122 #define DFL_ARC4                -1
123 #define DFL_SHA1                -1
124 #define DFL_AUTH_MODE           -1
125 #define DFL_MFL_CODE            MBEDTLS_SSL_MAX_FRAG_LEN_NONE
126 #define DFL_TRUNC_HMAC          -1
127 #define DFL_RECSPLIT            -1
128 #define DFL_DHMLEN              -1
129 #define DFL_RECONNECT           0
130 #define DFL_RECO_DELAY          0
131 #define DFL_RECONNECT_HARD      0
132 #define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
133 #define DFL_ALPN_STRING         NULL
134 #define DFL_CURVES              NULL
135 #define DFL_TRANSPORT           MBEDTLS_SSL_TRANSPORT_STREAM
136 #define DFL_HS_TO_MIN           0
137 #define DFL_HS_TO_MAX           0
138 #define DFL_DTLS_MTU            -1
139 #define DFL_DGRAM_PACKING        1
140 #define DFL_FALLBACK            -1
141 #define DFL_EXTENDED_MS         -1
142 #define DFL_ETM                 -1
143 #define DFL_SKIP_CLOSE_NOTIFY   0
144 
145 #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
146 #define GET_REQUEST_END "\r\n\r\n"
147 
148 #if defined(MBEDTLS_X509_CRT_PARSE_C)
149 #if defined(MBEDTLS_FS_IO)
150 #define USAGE_IO \
151     "    ca_file=%%s          The single file containing the top-level CA(s) you fully trust\n" \
152     "                        default: \"\" (pre-loaded)\n" \
153     "                        use \"none\" to skip loading any top-level CAs.\n" \
154     "    ca_path=%%s          The path containing the top-level CA(s) you fully trust\n" \
155     "                        default: \"\" (pre-loaded) (overrides ca_file)\n" \
156     "                        use \"none\" to skip loading any top-level CAs.\n" \
157     "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
158     "                        default: \"\" (pre-loaded)\n" \
159     "    key_file=%%s         default: \"\" (pre-loaded)\n"
160 #else
161 #define USAGE_IO \
162     "    No file operations available (MBEDTLS_FS_IO not defined)\n"
163 #endif /* MBEDTLS_FS_IO */
164 #else
165 #define USAGE_IO ""
166 #endif /* MBEDTLS_X509_CRT_PARSE_C */
167 
168 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
169 #define USAGE_PSK                                                   \
170     "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
171     "    psk_identity=%%s     default: \"Client_identity\"\n"
172 #else
173 #define USAGE_PSK ""
174 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
175 
176 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
177 #define USAGE_TICKETS                                       \
178     "    tickets=%%d          default: 1 (enabled)\n"
179 #else
180 #define USAGE_TICKETS ""
181 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
182 
183 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
184 #define USAGE_TRUNC_HMAC                                    \
185     "    trunc_hmac=%%d       default: library default\n"
186 #else
187 #define USAGE_TRUNC_HMAC ""
188 #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
189 
190 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
191 #define USAGE_MAX_FRAG_LEN                                      \
192     "    max_frag_len=%%d     default: 16384 (tls default)\n"   \
193     "                        options: 512, 1024, 2048, 4096\n"
194 #else
195 #define USAGE_MAX_FRAG_LEN ""
196 #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
197 
198 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
199 #define USAGE_RECSPLIT \
200     "    recsplit=0/1        default: (library default: on)\n"
201 #else
202 #define USAGE_RECSPLIT
203 #endif
204 
205 #if defined(MBEDTLS_DHM_C)
206 #define USAGE_DHMLEN \
207     "    dhmlen=%%d           default: (library default: 1024 bits)\n"
208 #else
209 #define USAGE_DHMLEN
210 #endif
211 
212 #if defined(MBEDTLS_SSL_ALPN)
213 #define USAGE_ALPN \
214     "    alpn=%%s             default: \"\" (disabled)\n"   \
215     "                        example: spdy/1,http/1.1\n"
216 #else
217 #define USAGE_ALPN ""
218 #endif /* MBEDTLS_SSL_ALPN */
219 
220 #if defined(MBEDTLS_ECP_C)
221 #define USAGE_CURVES \
222     "    curves=a,b,c,d      default: \"default\" (library default)\n"  \
223     "                        example: \"secp521r1,brainpoolP512r1\"\n"  \
224     "                        - use \"none\" for empty list\n"           \
225     "                        - see mbedtls_ecp_curve_list()\n"          \
226     "                          for acceptable curve names\n"
227 #else
228 #define USAGE_CURVES ""
229 #endif
230 
231 #if defined(MBEDTLS_SSL_PROTO_DTLS)
232 #define USAGE_DTLS \
233     "    dtls=%%d             default: 0 (TLS)\n"                           \
234     "    hs_timeout=%%d-%%d    default: (library default: 1000-60000)\n"    \
235     "                        range of DTLS handshake timeouts in millisecs\n" \
236     "    mtu=%%d              default: (library default: unlimited)\n"  \
237     "    dgram_packing=%%d    default: 1 (allowed)\n"                   \
238     "                        allow or forbid packing of multiple\n" \
239     "                        records within a single datgram.\n"
240 #else
241 #define USAGE_DTLS ""
242 #endif
243 
244 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
245 #define USAGE_FALLBACK \
246     "    fallback=0/1        default: (library default: off)\n"
247 #else
248 #define USAGE_FALLBACK ""
249 #endif
250 
251 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
252 #define USAGE_EMS \
253     "    extended_ms=0/1     default: (library default: on)\n"
254 #else
255 #define USAGE_EMS ""
256 #endif
257 
258 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
259 #define USAGE_ETM \
260     "    etm=0/1             default: (library default: on)\n"
261 #else
262 #define USAGE_ETM ""
263 #endif
264 
265 #if defined(MBEDTLS_SSL_RENEGOTIATION)
266 #define USAGE_RENEGO \
267     "    renegotiation=%%d    default: 0 (disabled)\n"      \
268     "    renegotiate=%%d      default: 0 (disabled)\n"
269 #else
270 #define USAGE_RENEGO ""
271 #endif
272 
273 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
274 #define USAGE_ECJPAKE \
275     "    ecjpake_pw=%%s       default: none (disabled)\n"
276 #else
277 #define USAGE_ECJPAKE ""
278 #endif
279 
280 #if defined(MBEDTLS_ECP_RESTARTABLE)
281 #define USAGE_ECRESTART \
282     "    ec_max_ops=%%s       default: library default (restart disabled)\n"
283 #else
284 #define USAGE_ECRESTART ""
285 #endif
286 
287 /* USAGE is arbitrarily split to stay under the portable string literal
288  * length limit: 4095 bytes in C99. */
289 #define USAGE1 \
290     "\n usage: ssl_client2 param=<>...\n"                   \
291     "\n acceptable parameters:\n"                           \
292     "    server_name=%%s      default: localhost\n"         \
293     "    server_addr=%%s      default: given by name\n"     \
294     "    server_port=%%d      default: 4433\n"              \
295     "    request_page=%%s     default: \".\"\n"             \
296     "    request_size=%%d     default: about 34 (basic request)\n"           \
297     "                        (minimum: 0, max: " MAX_REQUEST_SIZE_STR ")\n"  \
298     "                        If 0, in the first exchange only an empty\n"    \
299     "                        application data message is sent followed by\n" \
300     "                        a second non-empty message before attempting\n" \
301     "                        to read a response from the server\n"           \
302     "    debug_level=%%d      default: 0 (disabled)\n"             \
303     "    nbio=%%d             default: 0 (blocking I/O)\n"         \
304     "                        options: 1 (non-blocking), 2 (added delays)\n"   \
305     "    event=%%d            default: 0 (loop)\n"                            \
306     "                        options: 1 (level-triggered, implies nbio=1),\n" \
307     "    read_timeout=%%d     default: 0 ms (no timeout)\n"        \
308     "    max_resend=%%d       default: 0 (no resend on timeout)\n" \
309     "    skip_close_notify=%%d default: 0 (send close_notify)\n" \
310     "\n"                                                    \
311     USAGE_DTLS                                              \
312     "\n"
313 #define USAGE2 \
314     "    auth_mode=%%s        default: (library default: none)\n" \
315     "                        options: none, optional, required\n" \
316     USAGE_IO                                                \
317     "\n"                                                    \
318     USAGE_PSK                                               \
319     USAGE_ECJPAKE                                           \
320     USAGE_ECRESTART                                         \
321     "\n"
322 #define USAGE3 \
323     "    allow_legacy=%%d     default: (library default: no)\n"   \
324     USAGE_RENEGO                                            \
325     "    exchanges=%%d        default: 1\n"                 \
326     "    reconnect=%%d        default: 0 (disabled)\n"      \
327     "    reco_delay=%%d       default: 0 seconds\n"         \
328     "    reconnect_hard=%%d   default: 0 (disabled)\n"      \
329     USAGE_TICKETS                                           \
330     USAGE_MAX_FRAG_LEN                                      \
331     USAGE_TRUNC_HMAC                                        \
332     USAGE_ALPN                                              \
333     USAGE_FALLBACK                                          \
334     USAGE_EMS                                               \
335     USAGE_ETM                                               \
336     USAGE_CURVES                                            \
337     USAGE_RECSPLIT                                          \
338     USAGE_DHMLEN                                            \
339     "\n"
340 #define USAGE4 \
341     "    arc4=%%d             default: (library default: 0)\n" \
342     "    allow_sha1=%%d       default: 0\n"                             \
343     "    min_version=%%s      default: (library default: tls1)\n"       \
344     "    max_version=%%s      default: (library default: tls1_2)\n"     \
345     "    force_version=%%s    default: \"\" (none)\n"       \
346     "                        options: ssl3, tls1, tls1_1, tls1_2, dtls1, dtls1_2\n" \
347     "\n"                                                    \
348     "    force_ciphersuite=<name>    default: all enabled\n"\
349     "    query_config=<name>         return 0 if the specified\n"       \
350     "                                configuration macro is defined and 1\n"  \
351     "                                otherwise. The expansion of the macro\n" \
352     "                                is printed if it is defined\n"     \
353     " acceptable ciphersuite names:\n"
354 
355 #define ALPN_LIST_SIZE  10
356 #define CURVE_LIST_SIZE 20
357 
358 
359 /*
360  * global options
361  */
362 struct options
363 {
364     const char *server_name;    /* hostname of the server (client only)     */
365     const char *server_addr;    /* address of the server (client only)      */
366     const char *server_port;    /* port on which the ssl service runs       */
367     int debug_level;            /* level of debugging                       */
368     int nbio;                   /* should I/O be blocking?                  */
369     int event;                  /* loop or event-driven IO? level or edge triggered? */
370     uint32_t read_timeout;      /* timeout on mbedtls_ssl_read() in milliseconds     */
371     int max_resend;             /* DTLS times to resend on read timeout     */
372     const char *request_page;   /* page on server to request                */
373     int request_size;           /* pad request with header to requested size */
374     const char *ca_file;        /* the file with the CA certificate(s)      */
375     const char *ca_path;        /* the path with the CA certificate(s) reside */
376     const char *crt_file;       /* the file with the client certificate     */
377     const char *key_file;       /* the file with the client key             */
378     const char *psk;            /* the pre-shared key                       */
379     const char *psk_identity;   /* the pre-shared key identity              */
380     const char *ecjpake_pw;     /* the EC J-PAKE password                   */
381     int ec_max_ops;             /* EC consecutive operations limit          */
382     int force_ciphersuite[2];   /* protocol/ciphersuite to use, or all      */
383     int renegotiation;          /* enable / disable renegotiation           */
384     int allow_legacy;           /* allow legacy renegotiation               */
385     int renegotiate;            /* attempt renegotiation?                   */
386     int renego_delay;           /* delay before enforcing renegotiation     */
387     int exchanges;              /* number of data exchanges                 */
388     int min_version;            /* minimum protocol version accepted        */
389     int max_version;            /* maximum protocol version accepted        */
390     int arc4;                   /* flag for arc4 suites support             */
391     int allow_sha1;             /* flag for SHA-1 support                   */
392     int auth_mode;              /* verify mode for connection               */
393     unsigned char mfl_code;     /* code for maximum fragment length         */
394     int trunc_hmac;             /* negotiate truncated hmac or not          */
395     int recsplit;               /* enable record splitting?                 */
396     int dhmlen;                 /* minimum DHM params len in bits           */
397     int reconnect;              /* attempt to resume session                */
398     int reco_delay;             /* delay in seconds before resuming session */
399     int reconnect_hard;         /* unexpectedly reconnect from the same port */
400     int tickets;                /* enable / disable session tickets         */
401     const char *curves;         /* list of supported elliptic curves        */
402     const char *alpn_string;    /* ALPN supported protocols                 */
403     int transport;              /* TLS or DTLS?                             */
404     uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
405     uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
406     int dtls_mtu;               /* UDP Maximum tranport unit for DTLS       */
407     int fallback;               /* is this a fallback connection?           */
408     int dgram_packing;          /* allow/forbid datagram packing            */
409     int extended_ms;            /* negotiate extended master secret?        */
410     int etm;                    /* negotiate encrypt then mac?              */
411     int skip_close_notify;      /* skip sending the close_notify alert      */
412 } opt;
413 
414 int query_config( const char *config );
415 
my_debug(void * ctx,int level,const char * file,int line,const char * str)416 static void my_debug( void *ctx, int level,
417                       const char *file, int line,
418                       const char *str )
419 {
420     const char *p, *basename;
421 
422     /* Extract basename from file */
423     for( p = basename = file; *p != '\0'; p++ )
424         if( *p == '/' || *p == '\\' )
425             basename = p + 1;
426 
427     mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s",
428                      basename, line, level, str );
429     fflush(  (FILE *) ctx  );
430 }
431 
432 /*
433  * Test recv/send functions that make sure each try returns
434  * WANT_READ/WANT_WRITE at least once before sucesseding
435  */
my_recv(void * ctx,unsigned char * buf,size_t len)436 static int my_recv( void *ctx, unsigned char *buf, size_t len )
437 {
438     static int first_try = 1;
439     int ret;
440 
441     if( first_try )
442     {
443         first_try = 0;
444         return( MBEDTLS_ERR_SSL_WANT_READ );
445     }
446 
447     ret = mbedtls_net_recv( ctx, buf, len );
448     if( ret != MBEDTLS_ERR_SSL_WANT_READ )
449         first_try = 1; /* Next call will be a new operation */
450     return( ret );
451 }
452 
my_send(void * ctx,const unsigned char * buf,size_t len)453 static int my_send( void *ctx, const unsigned char *buf, size_t len )
454 {
455     static int first_try = 1;
456     int ret;
457 
458     if( first_try )
459     {
460         first_try = 0;
461         return( MBEDTLS_ERR_SSL_WANT_WRITE );
462     }
463 
464     ret = mbedtls_net_send( ctx, buf, len );
465     if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
466         first_try = 1; /* Next call will be a new operation */
467     return( ret );
468 }
469 
470 #if defined(MBEDTLS_X509_CRT_PARSE_C)
471 /*
472  * Enabled if debug_level > 1 in code below
473  */
my_verify(void * data,mbedtls_x509_crt * crt,int depth,uint32_t * flags)474 static int my_verify( void *data, mbedtls_x509_crt *crt,
475                       int depth, uint32_t *flags )
476 {
477     char buf[1024];
478     ((void) data);
479 
480     mbedtls_printf( "\nVerify requested for (Depth %d):\n", depth );
481     mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
482     mbedtls_printf( "%s", buf );
483 
484     if ( ( *flags ) == 0 )
485         mbedtls_printf( "  This certificate has no flags\n" );
486     else
487     {
488         mbedtls_x509_crt_verify_info( buf, sizeof( buf ), "  ! ", *flags );
489         mbedtls_printf( "%s\n", buf );
490     }
491 
492     return( 0 );
493 }
494 
495 static int ssl_sig_hashes_for_test[] = {
496 #if defined(MBEDTLS_SHA512_C)
497     MBEDTLS_MD_SHA512,
498     MBEDTLS_MD_SHA384,
499 #endif
500 #if defined(MBEDTLS_SHA256_C)
501     MBEDTLS_MD_SHA256,
502     MBEDTLS_MD_SHA224,
503 #endif
504 #if defined(MBEDTLS_SHA1_C)
505     /* Allow SHA-1 as we use it extensively in tests. */
506     MBEDTLS_MD_SHA1,
507 #endif
508     MBEDTLS_MD_NONE
509 };
510 #endif /* MBEDTLS_X509_CRT_PARSE_C */
511 
512 /*
513  * Wait for an event from the underlying transport or the timer
514  * (Used in event-driven IO mode).
515  */
516 #if !defined(MBEDTLS_TIMING_C)
idle(mbedtls_net_context * fd,int idle_reason)517 int idle( mbedtls_net_context *fd,
518           int idle_reason )
519 #else
520 int idle( mbedtls_net_context *fd,
521           mbedtls_timing_delay_context *timer,
522           int idle_reason )
523 #endif
524 {
525 
526     int ret;
527     int poll_type = 0;
528 
529     if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE )
530         poll_type = MBEDTLS_NET_POLL_WRITE;
531     else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ )
532         poll_type = MBEDTLS_NET_POLL_READ;
533 #if !defined(MBEDTLS_TIMING_C)
534     else
535         return( 0 );
536 #endif
537 
538     while( 1 )
539     {
540         /* Check if timer has expired */
541 #if defined(MBEDTLS_TIMING_C)
542         if( timer != NULL &&
543             mbedtls_timing_get_delay( timer ) == 2 )
544         {
545             break;
546         }
547 #endif /* MBEDTLS_TIMING_C */
548 
549         /* Check if underlying transport became available */
550         if( poll_type != 0 )
551         {
552             ret = mbedtls_net_poll( fd, poll_type, 0 );
553             if( ret < 0 )
554                 return( ret );
555             if( ret == poll_type )
556                 break;
557         }
558     }
559 
560     return( 0 );
561 }
562 
main(int argc,char * argv[])563 int main( int argc, char *argv[] )
564 {
565     int ret = 0, len, tail_len, i, written, frags, retry_left;
566     mbedtls_net_context server_fd;
567 
568     unsigned char buf[MAX_REQUEST_SIZE + 1];
569 
570 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
571     unsigned char psk[MBEDTLS_PSK_MAX_LEN];
572     size_t psk_len = 0;
573 #endif
574 #if defined(MBEDTLS_SSL_ALPN)
575     const char *alpn_list[ALPN_LIST_SIZE];
576 #endif
577 #if defined(MBEDTLS_ECP_C)
578     mbedtls_ecp_group_id curve_list[CURVE_LIST_SIZE];
579     const mbedtls_ecp_curve_info *curve_cur;
580 #endif
581 
582     const char *pers = "ssl_client2";
583 
584 #if defined(MBEDTLS_X509_CRT_PARSE_C)
585     mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
586 #endif
587     mbedtls_entropy_context entropy;
588     mbedtls_ctr_drbg_context ctr_drbg;
589     mbedtls_ssl_context ssl;
590     mbedtls_ssl_config conf;
591     mbedtls_ssl_session saved_session;
592 #if defined(MBEDTLS_TIMING_C)
593     mbedtls_timing_delay_context timer;
594 #endif
595 #if defined(MBEDTLS_X509_CRT_PARSE_C)
596     uint32_t flags;
597     mbedtls_x509_crt cacert;
598     mbedtls_x509_crt clicert;
599     mbedtls_pk_context pkey;
600 #endif
601     char *p, *q;
602     const int *list;
603 
604     /*
605      * Make sure memory references are valid.
606      */
607     mbedtls_net_init( &server_fd );
608     mbedtls_ssl_init( &ssl );
609     mbedtls_ssl_config_init( &conf );
610     memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) );
611     mbedtls_ctr_drbg_init( &ctr_drbg );
612 #if defined(MBEDTLS_X509_CRT_PARSE_C)
613     mbedtls_x509_crt_init( &cacert );
614     mbedtls_x509_crt_init( &clicert );
615     mbedtls_pk_init( &pkey );
616 #endif
617 #if defined(MBEDTLS_SSL_ALPN)
618     memset( (void * ) alpn_list, 0, sizeof( alpn_list ) );
619 #endif
620 
621     if( argc == 0 )
622     {
623     usage:
624         if( ret == 0 )
625             ret = 1;
626 
627         mbedtls_printf( USAGE1 );
628         mbedtls_printf( USAGE2 );
629         mbedtls_printf( USAGE3 );
630         mbedtls_printf( USAGE4 );
631 
632         list = mbedtls_ssl_list_ciphersuites();
633         while( *list )
634         {
635             mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name( *list ) );
636             list++;
637             if( !*list )
638                 break;
639             mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name( *list ) );
640             list++;
641         }
642         mbedtls_printf("\n");
643         goto exit;
644     }
645 
646     opt.server_name         = DFL_SERVER_NAME;
647     opt.server_addr         = DFL_SERVER_ADDR;
648     opt.server_port         = DFL_SERVER_PORT;
649     opt.debug_level         = DFL_DEBUG_LEVEL;
650     opt.nbio                = DFL_NBIO;
651     opt.event               = DFL_EVENT;
652     opt.read_timeout        = DFL_READ_TIMEOUT;
653     opt.max_resend          = DFL_MAX_RESEND;
654     opt.request_page        = DFL_REQUEST_PAGE;
655     opt.request_size        = DFL_REQUEST_SIZE;
656     opt.ca_file             = DFL_CA_FILE;
657     opt.ca_path             = DFL_CA_PATH;
658     opt.crt_file            = DFL_CRT_FILE;
659     opt.key_file            = DFL_KEY_FILE;
660     opt.psk                 = DFL_PSK;
661     opt.psk_identity        = DFL_PSK_IDENTITY;
662     opt.ecjpake_pw          = DFL_ECJPAKE_PW;
663     opt.ec_max_ops          = DFL_EC_MAX_OPS;
664     opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
665     opt.renegotiation       = DFL_RENEGOTIATION;
666     opt.allow_legacy        = DFL_ALLOW_LEGACY;
667     opt.renegotiate         = DFL_RENEGOTIATE;
668     opt.exchanges           = DFL_EXCHANGES;
669     opt.min_version         = DFL_MIN_VERSION;
670     opt.max_version         = DFL_MAX_VERSION;
671     opt.arc4                = DFL_ARC4;
672     opt.allow_sha1          = DFL_SHA1;
673     opt.auth_mode           = DFL_AUTH_MODE;
674     opt.mfl_code            = DFL_MFL_CODE;
675     opt.trunc_hmac          = DFL_TRUNC_HMAC;
676     opt.recsplit            = DFL_RECSPLIT;
677     opt.dhmlen              = DFL_DHMLEN;
678     opt.reconnect           = DFL_RECONNECT;
679     opt.reco_delay          = DFL_RECO_DELAY;
680     opt.reconnect_hard      = DFL_RECONNECT_HARD;
681     opt.tickets             = DFL_TICKETS;
682     opt.alpn_string         = DFL_ALPN_STRING;
683     opt.curves              = DFL_CURVES;
684     opt.transport           = DFL_TRANSPORT;
685     opt.hs_to_min           = DFL_HS_TO_MIN;
686     opt.hs_to_max           = DFL_HS_TO_MAX;
687     opt.dtls_mtu            = DFL_DTLS_MTU;
688     opt.fallback            = DFL_FALLBACK;
689     opt.extended_ms         = DFL_EXTENDED_MS;
690     opt.etm                 = DFL_ETM;
691     opt.dgram_packing       = DFL_DGRAM_PACKING;
692     opt.skip_close_notify   = DFL_SKIP_CLOSE_NOTIFY;
693 
694     for( i = 1; i < argc; i++ )
695     {
696         p = argv[i];
697         if( ( q = strchr( p, '=' ) ) == NULL )
698             goto usage;
699         *q++ = '\0';
700 
701         if( strcmp( p, "server_name" ) == 0 )
702             opt.server_name = q;
703         else if( strcmp( p, "server_addr" ) == 0 )
704             opt.server_addr = q;
705         else if( strcmp( p, "server_port" ) == 0 )
706             opt.server_port = q;
707         else if( strcmp( p, "dtls" ) == 0 )
708         {
709             int t = atoi( q );
710             if( t == 0 )
711                 opt.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
712             else if( t == 1 )
713                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
714             else
715                 goto usage;
716         }
717         else if( strcmp( p, "debug_level" ) == 0 )
718         {
719             opt.debug_level = atoi( q );
720             if( opt.debug_level < 0 || opt.debug_level > 65535 )
721                 goto usage;
722         }
723         else if( strcmp( p, "nbio" ) == 0 )
724         {
725             opt.nbio = atoi( q );
726             if( opt.nbio < 0 || opt.nbio > 2 )
727                 goto usage;
728         }
729         else if( strcmp( p, "event" ) == 0 )
730         {
731             opt.event = atoi( q );
732             if( opt.event < 0 || opt.event > 2 )
733                 goto usage;
734         }
735         else if( strcmp( p, "read_timeout" ) == 0 )
736             opt.read_timeout = atoi( q );
737         else if( strcmp( p, "max_resend" ) == 0 )
738         {
739             opt.max_resend = atoi( q );
740             if( opt.max_resend < 0 )
741                 goto usage;
742         }
743         else if( strcmp( p, "request_page" ) == 0 )
744             opt.request_page = q;
745         else if( strcmp( p, "request_size" ) == 0 )
746         {
747             opt.request_size = atoi( q );
748             if( opt.request_size < 0 ||
749                 opt.request_size > MAX_REQUEST_SIZE )
750                 goto usage;
751         }
752         else if( strcmp( p, "ca_file" ) == 0 )
753             opt.ca_file = q;
754         else if( strcmp( p, "ca_path" ) == 0 )
755             opt.ca_path = q;
756         else if( strcmp( p, "crt_file" ) == 0 )
757             opt.crt_file = q;
758         else if( strcmp( p, "key_file" ) == 0 )
759             opt.key_file = q;
760         else if( strcmp( p, "psk" ) == 0 )
761             opt.psk = q;
762         else if( strcmp( p, "psk_identity" ) == 0 )
763             opt.psk_identity = q;
764         else if( strcmp( p, "ecjpake_pw" ) == 0 )
765             opt.ecjpake_pw = q;
766         else if( strcmp( p, "ec_max_ops" ) == 0 )
767             opt.ec_max_ops = atoi( q );
768         else if( strcmp( p, "force_ciphersuite" ) == 0 )
769         {
770             opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
771 
772             if( opt.force_ciphersuite[0] == 0 )
773             {
774                 ret = 2;
775                 goto usage;
776             }
777             opt.force_ciphersuite[1] = 0;
778         }
779         else if( strcmp( p, "renegotiation" ) == 0 )
780         {
781             opt.renegotiation = (atoi( q )) ?
782                 MBEDTLS_SSL_RENEGOTIATION_ENABLED :
783                 MBEDTLS_SSL_RENEGOTIATION_DISABLED;
784         }
785         else if( strcmp( p, "allow_legacy" ) == 0 )
786         {
787             switch( atoi( q ) )
788             {
789                 case -1:
790                     opt.allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE;
791                     break;
792                 case 0:
793                     opt.allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
794                     break;
795                 case 1:
796                     opt.allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION;
797                     break;
798                 default: goto usage;
799             }
800         }
801         else if( strcmp( p, "renegotiate" ) == 0 )
802         {
803             opt.renegotiate = atoi( q );
804             if( opt.renegotiate < 0 || opt.renegotiate > 1 )
805                 goto usage;
806         }
807         else if( strcmp( p, "exchanges" ) == 0 )
808         {
809             opt.exchanges = atoi( q );
810             if( opt.exchanges < 1 )
811                 goto usage;
812         }
813         else if( strcmp( p, "reconnect" ) == 0 )
814         {
815             opt.reconnect = atoi( q );
816             if( opt.reconnect < 0 || opt.reconnect > 2 )
817                 goto usage;
818         }
819         else if( strcmp( p, "reco_delay" ) == 0 )
820         {
821             opt.reco_delay = atoi( q );
822             if( opt.reco_delay < 0 )
823                 goto usage;
824         }
825         else if( strcmp( p, "reconnect_hard" ) == 0 )
826         {
827             opt.reconnect_hard = atoi( q );
828             if( opt.reconnect_hard < 0 || opt.reconnect_hard > 1 )
829                 goto usage;
830         }
831         else if( strcmp( p, "tickets" ) == 0 )
832         {
833             opt.tickets = atoi( q );
834             if( opt.tickets < 0 || opt.tickets > 2 )
835                 goto usage;
836         }
837         else if( strcmp( p, "alpn" ) == 0 )
838         {
839             opt.alpn_string = q;
840         }
841         else if( strcmp( p, "fallback" ) == 0 )
842         {
843             switch( atoi( q ) )
844             {
845                 case 0: opt.fallback = MBEDTLS_SSL_IS_NOT_FALLBACK; break;
846                 case 1: opt.fallback = MBEDTLS_SSL_IS_FALLBACK; break;
847                 default: goto usage;
848             }
849         }
850         else if( strcmp( p, "extended_ms" ) == 0 )
851         {
852             switch( atoi( q ) )
853             {
854                 case 0:
855                     opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED;
856                     break;
857                 case 1:
858                     opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
859                     break;
860                 default: goto usage;
861             }
862         }
863         else if( strcmp( p, "curves" ) == 0 )
864             opt.curves = q;
865         else if( strcmp( p, "etm" ) == 0 )
866         {
867             switch( atoi( q ) )
868             {
869                 case 0: opt.etm = MBEDTLS_SSL_ETM_DISABLED; break;
870                 case 1: opt.etm = MBEDTLS_SSL_ETM_ENABLED; break;
871                 default: goto usage;
872             }
873         }
874         else if( strcmp( p, "min_version" ) == 0 )
875         {
876             if( strcmp( q, "ssl3" ) == 0 )
877                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
878             else if( strcmp( q, "tls1" ) == 0 )
879                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
880             else if( strcmp( q, "tls1_1" ) == 0 ||
881                      strcmp( q, "dtls1" ) == 0 )
882                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
883             else if( strcmp( q, "tls1_2" ) == 0 ||
884                      strcmp( q, "dtls1_2" ) == 0 )
885                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
886             else
887                 goto usage;
888         }
889         else if( strcmp( p, "max_version" ) == 0 )
890         {
891             if( strcmp( q, "ssl3" ) == 0 )
892                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
893             else if( strcmp( q, "tls1" ) == 0 )
894                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
895             else if( strcmp( q, "tls1_1" ) == 0 ||
896                      strcmp( q, "dtls1" ) == 0 )
897                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
898             else if( strcmp( q, "tls1_2" ) == 0 ||
899                      strcmp( q, "dtls1_2" ) == 0 )
900                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
901             else
902                 goto usage;
903         }
904         else if( strcmp( p, "arc4" ) == 0 )
905         {
906             switch( atoi( q ) )
907             {
908                 case 0:     opt.arc4 = MBEDTLS_SSL_ARC4_DISABLED;   break;
909                 case 1:     opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;    break;
910                 default:    goto usage;
911             }
912         }
913         else if( strcmp( p, "allow_sha1" ) == 0 )
914         {
915             switch( atoi( q ) )
916             {
917                 case 0:     opt.allow_sha1 = 0;   break;
918                 case 1:     opt.allow_sha1 = 1;    break;
919                 default:    goto usage;
920             }
921         }
922         else if( strcmp( p, "force_version" ) == 0 )
923         {
924             if( strcmp( q, "ssl3" ) == 0 )
925             {
926                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
927                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
928             }
929             else if( strcmp( q, "tls1" ) == 0 )
930             {
931                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
932                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
933             }
934             else if( strcmp( q, "tls1_1" ) == 0 )
935             {
936                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
937                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
938             }
939             else if( strcmp( q, "tls1_2" ) == 0 )
940             {
941                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
942                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
943             }
944             else if( strcmp( q, "dtls1" ) == 0 )
945             {
946                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
947                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
948                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
949             }
950             else if( strcmp( q, "dtls1_2" ) == 0 )
951             {
952                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
953                 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
954                 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
955             }
956             else
957                 goto usage;
958         }
959         else if( strcmp( p, "auth_mode" ) == 0 )
960         {
961             if( strcmp( q, "none" ) == 0 )
962                 opt.auth_mode = MBEDTLS_SSL_VERIFY_NONE;
963             else if( strcmp( q, "optional" ) == 0 )
964                 opt.auth_mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
965             else if( strcmp( q, "required" ) == 0 )
966                 opt.auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED;
967             else
968                 goto usage;
969         }
970         else if( strcmp( p, "max_frag_len" ) == 0 )
971         {
972             if( strcmp( q, "512" ) == 0 )
973                 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512;
974             else if( strcmp( q, "1024" ) == 0 )
975                 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_1024;
976             else if( strcmp( q, "2048" ) == 0 )
977                 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_2048;
978             else if( strcmp( q, "4096" ) == 0 )
979                 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_4096;
980             else
981                 goto usage;
982         }
983         else if( strcmp( p, "trunc_hmac" ) == 0 )
984         {
985             switch( atoi( q ) )
986             {
987                 case 0: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED; break;
988                 case 1: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; break;
989                 default: goto usage;
990             }
991         }
992         else if( strcmp( p, "hs_timeout" ) == 0 )
993         {
994             if( ( p = strchr( q, '-' ) ) == NULL )
995                 goto usage;
996             *p++ = '\0';
997             opt.hs_to_min = atoi( q );
998             opt.hs_to_max = atoi( p );
999             if( opt.hs_to_min == 0 || opt.hs_to_max < opt.hs_to_min )
1000                 goto usage;
1001         }
1002         else if( strcmp( p, "mtu" ) == 0 )
1003         {
1004             opt.dtls_mtu = atoi( q );
1005             if( opt.dtls_mtu < 0 )
1006                 goto usage;
1007         }
1008         else if( strcmp( p, "dgram_packing" ) == 0 )
1009         {
1010             opt.dgram_packing = atoi( q );
1011             if( opt.dgram_packing != 0 &&
1012                 opt.dgram_packing != 1 )
1013             {
1014                 goto usage;
1015             }
1016         }
1017         else if( strcmp( p, "recsplit" ) == 0 )
1018         {
1019             opt.recsplit = atoi( q );
1020             if( opt.recsplit < 0 || opt.recsplit > 1 )
1021                 goto usage;
1022         }
1023         else if( strcmp( p, "dhmlen" ) == 0 )
1024         {
1025             opt.dhmlen = atoi( q );
1026             if( opt.dhmlen < 0 )
1027                 goto usage;
1028         }
1029         else if( strcmp( p, "query_config" ) == 0 )
1030         {
1031             mbedtls_exit( query_config( q ) );
1032         }
1033         else if( strcmp( p, "skip_close_notify" ) == 0 )
1034         {
1035             opt.skip_close_notify = atoi( q );
1036             if( opt.skip_close_notify < 0 || opt.skip_close_notify > 1 )
1037                 goto usage;
1038         }
1039         else
1040             goto usage;
1041     }
1042 
1043     /* Event-driven IO is incompatible with the above custom
1044      * receive and send functions, as the polling builds on
1045      * refers to the underlying net_context. */
1046     if( opt.event == 1 && opt.nbio != 1 )
1047     {
1048         mbedtls_printf( "Warning: event-driven IO mandates nbio=1 - overwrite\n" );
1049         opt.nbio = 1;
1050     }
1051 
1052 #if defined(MBEDTLS_DEBUG_C)
1053     mbedtls_debug_set_threshold( opt.debug_level );
1054 #endif
1055 
1056     if( opt.force_ciphersuite[0] > 0 )
1057     {
1058         const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
1059         ciphersuite_info =
1060             mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
1061 
1062         if( opt.max_version != -1 &&
1063             ciphersuite_info->min_minor_ver > opt.max_version )
1064         {
1065             mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
1066             ret = 2;
1067             goto usage;
1068         }
1069         if( opt.min_version != -1 &&
1070             ciphersuite_info->max_minor_ver < opt.min_version )
1071         {
1072             mbedtls_printf( "forced ciphersuite not allowed with this protocol version\n" );
1073             ret = 2;
1074             goto usage;
1075         }
1076 
1077         /* If the server selects a version that's not supported by
1078          * this suite, then there will be no common ciphersuite... */
1079         if( opt.max_version == -1 ||
1080             opt.max_version > ciphersuite_info->max_minor_ver )
1081         {
1082             opt.max_version = ciphersuite_info->max_minor_ver;
1083         }
1084         if( opt.min_version < ciphersuite_info->min_minor_ver )
1085         {
1086             opt.min_version = ciphersuite_info->min_minor_ver;
1087             /* DTLS starts with TLS 1.1 */
1088             if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
1089                 opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
1090                 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
1091         }
1092 
1093         /* Enable RC4 if needed and not explicitly disabled */
1094         if( ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
1095         {
1096             if( opt.arc4 == MBEDTLS_SSL_ARC4_DISABLED )
1097             {
1098                 mbedtls_printf( "forced RC4 ciphersuite with RC4 disabled\n" );
1099                 ret = 2;
1100                 goto usage;
1101             }
1102 
1103             opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
1104         }
1105     }
1106 
1107 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1108     /*
1109      * Unhexify the pre-shared key if any is given
1110      */
1111     if( strlen( opt.psk ) )
1112     {
1113         unsigned char c;
1114         size_t j;
1115 
1116         if( strlen( opt.psk ) % 2 != 0 )
1117         {
1118             mbedtls_printf( "pre-shared key not valid hex\n" );
1119             goto exit;
1120         }
1121 
1122         psk_len = strlen( opt.psk ) / 2;
1123 
1124         for( j = 0; j < strlen( opt.psk ); j += 2 )
1125         {
1126             c = opt.psk[j];
1127             if( c >= '0' && c <= '9' )
1128                 c -= '0';
1129             else if( c >= 'a' && c <= 'f' )
1130                 c -= 'a' - 10;
1131             else if( c >= 'A' && c <= 'F' )
1132                 c -= 'A' - 10;
1133             else
1134             {
1135                 mbedtls_printf( "pre-shared key not valid hex\n" );
1136                 goto exit;
1137             }
1138             psk[ j / 2 ] = c << 4;
1139 
1140             c = opt.psk[j + 1];
1141             if( c >= '0' && c <= '9' )
1142                 c -= '0';
1143             else if( c >= 'a' && c <= 'f' )
1144                 c -= 'a' - 10;
1145             else if( c >= 'A' && c <= 'F' )
1146                 c -= 'A' - 10;
1147             else
1148             {
1149                 mbedtls_printf( "pre-shared key not valid hex\n" );
1150                 goto exit;
1151             }
1152             psk[ j / 2 ] |= c;
1153         }
1154     }
1155 #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
1156 
1157 #if defined(MBEDTLS_ECP_C)
1158     if( opt.curves != NULL )
1159     {
1160         p = (char *) opt.curves;
1161         i = 0;
1162 
1163         if( strcmp( p, "none" ) == 0 )
1164         {
1165             curve_list[0] = MBEDTLS_ECP_DP_NONE;
1166         }
1167         else if( strcmp( p, "default" ) != 0 )
1168         {
1169             /* Leave room for a final NULL in curve list */
1170             while( i < CURVE_LIST_SIZE - 1 && *p != '\0' )
1171             {
1172                 q = p;
1173 
1174                 /* Terminate the current string */
1175                 while( *p != ',' && *p != '\0' )
1176                     p++;
1177                 if( *p == ',' )
1178                     *p++ = '\0';
1179 
1180                 if( ( curve_cur = mbedtls_ecp_curve_info_from_name( q ) ) != NULL )
1181                 {
1182                     curve_list[i++] = curve_cur->grp_id;
1183                 }
1184                 else
1185                 {
1186                     mbedtls_printf( "unknown curve %s\n", q );
1187                     mbedtls_printf( "supported curves: " );
1188                     for( curve_cur = mbedtls_ecp_curve_list();
1189                          curve_cur->grp_id != MBEDTLS_ECP_DP_NONE;
1190                          curve_cur++ )
1191                     {
1192                         mbedtls_printf( "%s ", curve_cur->name );
1193                     }
1194                     mbedtls_printf( "\n" );
1195                     goto exit;
1196                 }
1197             }
1198 
1199             mbedtls_printf("Number of curves: %d\n", i );
1200 
1201             if( i == CURVE_LIST_SIZE - 1 && *p != '\0' )
1202             {
1203                 mbedtls_printf( "curves list too long, maximum %d",
1204                                 CURVE_LIST_SIZE - 1 );
1205                 goto exit;
1206             }
1207 
1208             curve_list[i] = MBEDTLS_ECP_DP_NONE;
1209         }
1210     }
1211 #endif /* MBEDTLS_ECP_C */
1212 
1213 #if defined(MBEDTLS_SSL_ALPN)
1214     if( opt.alpn_string != NULL )
1215     {
1216         p = (char *) opt.alpn_string;
1217         i = 0;
1218 
1219         /* Leave room for a final NULL in alpn_list */
1220         while( i < ALPN_LIST_SIZE - 1 && *p != '\0' )
1221         {
1222             alpn_list[i++] = p;
1223 
1224             /* Terminate the current string and move on to next one */
1225             while( *p != ',' && *p != '\0' )
1226                 p++;
1227             if( *p == ',' )
1228                 *p++ = '\0';
1229         }
1230     }
1231 #endif /* MBEDTLS_SSL_ALPN */
1232 
1233     /*
1234      * 0. Initialize the RNG and the session data
1235      */
1236     mbedtls_printf( "\n  . Seeding the random number generator..." );
1237     fflush( stdout );
1238 
1239     mbedtls_entropy_init( &entropy );
1240     if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
1241                                        &entropy, (const unsigned char *) pers,
1242                                        strlen( pers ) ) ) != 0 )
1243     {
1244         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
1245                         -ret );
1246         goto exit;
1247     }
1248 
1249     mbedtls_printf( " ok\n" );
1250 
1251 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1252     /*
1253      * 1.1. Load the trusted CA
1254      */
1255     mbedtls_printf( "  . Loading the CA root certificate ..." );
1256     fflush( stdout );
1257 
1258     if( strcmp( opt.ca_path, "none" ) == 0 ||
1259         strcmp( opt.ca_file, "none" ) == 0 )
1260     {
1261         ret = 0;
1262     }
1263     else
1264 #if defined(MBEDTLS_FS_IO)
1265     if( strlen( opt.ca_path ) )
1266         ret = mbedtls_x509_crt_parse_path( &cacert, opt.ca_path );
1267     else if( strlen( opt.ca_file ) )
1268         ret = mbedtls_x509_crt_parse_file( &cacert, opt.ca_file );
1269     else
1270 #endif
1271 #if defined(MBEDTLS_CERTS_C)
1272     {
1273 #if defined(MBEDTLS_PEM_PARSE_C)
1274         for( i = 0; mbedtls_test_cas[i] != NULL; i++ )
1275         {
1276             ret = mbedtls_x509_crt_parse( &cacert,
1277                                   (const unsigned char *) mbedtls_test_cas[i],
1278                                   mbedtls_test_cas_len[i] );
1279             if( ret != 0 )
1280                 break;
1281         }
1282         if( ret == 0 )
1283 #endif /* MBEDTLS_PEM_PARSE_C */
1284         for( i = 0; mbedtls_test_cas_der[i] != NULL; i++ )
1285         {
1286             ret = mbedtls_x509_crt_parse_der( &cacert,
1287                          (const unsigned char *) mbedtls_test_cas_der[i],
1288                          mbedtls_test_cas_der_len[i] );
1289             if( ret != 0 )
1290                 break;
1291         }
1292     }
1293 #else
1294     {
1295         ret = 1;
1296         mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
1297     }
1298 #endif /* MBEDTLS_CERTS_C */
1299     if( ret < 0 )
1300     {
1301         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
1302                         -ret );
1303         goto exit;
1304     }
1305 
1306     mbedtls_printf( " ok (%d skipped)\n", ret );
1307 
1308     /*
1309      * 1.2. Load own certificate and private key
1310      *
1311      * (can be skipped if client authentication is not required)
1312      */
1313     mbedtls_printf( "  . Loading the client cert. and key..." );
1314     fflush( stdout );
1315 
1316     if( strcmp( opt.crt_file, "none" ) == 0 )
1317         ret = 0;
1318     else
1319 #if defined(MBEDTLS_FS_IO)
1320     if( strlen( opt.crt_file ) )
1321         ret = mbedtls_x509_crt_parse_file( &clicert, opt.crt_file );
1322     else
1323 #endif
1324 #if defined(MBEDTLS_CERTS_C)
1325         ret = mbedtls_x509_crt_parse( &clicert,
1326                 (const unsigned char *) mbedtls_test_cli_crt,
1327                 mbedtls_test_cli_crt_len );
1328 #else
1329     {
1330         ret = 1;
1331         mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
1332     }
1333 #endif
1334     if( ret != 0 )
1335     {
1336         mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
1337                         -ret );
1338         goto exit;
1339     }
1340 
1341     if( strcmp( opt.key_file, "none" ) == 0 )
1342         ret = 0;
1343     else
1344 #if defined(MBEDTLS_FS_IO)
1345     if( strlen( opt.key_file ) )
1346         ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" );
1347     else
1348 #endif
1349 #if defined(MBEDTLS_CERTS_C)
1350         ret = mbedtls_pk_parse_key( &pkey,
1351                 (const unsigned char *) mbedtls_test_cli_key,
1352                 mbedtls_test_cli_key_len, NULL, 0 );
1353 #else
1354     {
1355         ret = 1;
1356         mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
1357     }
1358 #endif
1359     if( ret != 0 )
1360     {
1361         mbedtls_printf( " failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n",
1362                         -ret );
1363         goto exit;
1364     }
1365 
1366     mbedtls_printf( " ok\n" );
1367 #endif /* MBEDTLS_X509_CRT_PARSE_C */
1368 
1369     /*
1370      * 2. Start the connection
1371      */
1372     if( opt.server_addr == NULL)
1373         opt.server_addr = opt.server_name;
1374 
1375     mbedtls_printf( "  . Connecting to %s/%s/%s...",
1376             opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ? "tcp" : "udp",
1377             opt.server_addr, opt.server_port );
1378     fflush( stdout );
1379 
1380     if( ( ret = mbedtls_net_connect( &server_fd,
1381                        opt.server_addr, opt.server_port,
1382                        opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
1383                        MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) != 0 )
1384     {
1385         mbedtls_printf( " failed\n  ! mbedtls_net_connect returned -0x%x\n\n",
1386                         -ret );
1387         goto exit;
1388     }
1389 
1390     if( opt.nbio > 0 )
1391         ret = mbedtls_net_set_nonblock( &server_fd );
1392     else
1393         ret = mbedtls_net_set_block( &server_fd );
1394     if( ret != 0 )
1395     {
1396         mbedtls_printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n",
1397                         -ret );
1398         goto exit;
1399     }
1400 
1401     mbedtls_printf( " ok\n" );
1402 
1403     /*
1404      * 3. Setup stuff
1405      */
1406     mbedtls_printf( "  . Setting up the SSL/TLS structure..." );
1407     fflush( stdout );
1408 
1409     if( ( ret = mbedtls_ssl_config_defaults( &conf,
1410                     MBEDTLS_SSL_IS_CLIENT,
1411                     opt.transport,
1412                     MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
1413     {
1414         mbedtls_printf( " failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n",
1415                         -ret );
1416         goto exit;
1417     }
1418 
1419 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1420     /* The default algorithms profile disables SHA-1, but our tests still
1421        rely on it heavily. */
1422     if( opt.allow_sha1 > 0 )
1423     {
1424         crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
1425         mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
1426         mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
1427     }
1428 
1429     if( opt.debug_level > 0 )
1430         mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
1431 #endif /* MBEDTLS_X509_CRT_PARSE_C */
1432 
1433     if( opt.auth_mode != DFL_AUTH_MODE )
1434         mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
1435 
1436 #if defined(MBEDTLS_SSL_PROTO_DTLS)
1437     if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
1438         mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min,
1439                                             opt.hs_to_max );
1440 
1441     if( opt.dgram_packing != DFL_DGRAM_PACKING )
1442         mbedtls_ssl_set_datagram_packing( &ssl, opt.dgram_packing );
1443 #endif /* MBEDTLS_SSL_PROTO_DTLS */
1444 
1445 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1446     if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
1447     {
1448         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n",
1449                         ret );
1450         goto exit;
1451     }
1452 #endif
1453 
1454 #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1455     if( opt.trunc_hmac != DFL_TRUNC_HMAC )
1456         mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
1457 #endif
1458 
1459 #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1460     if( opt.extended_ms != DFL_EXTENDED_MS )
1461         mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
1462 #endif
1463 
1464 #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1465     if( opt.etm != DFL_ETM )
1466         mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
1467 #endif
1468 
1469 #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
1470     if( opt.recsplit != DFL_RECSPLIT )
1471         mbedtls_ssl_conf_cbc_record_splitting( &conf, opt.recsplit
1472                                   ? MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED
1473                                   : MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED );
1474 #endif
1475 
1476 #if defined(MBEDTLS_DHM_C)
1477     if( opt.dhmlen != DFL_DHMLEN )
1478         mbedtls_ssl_conf_dhm_min_bitlen( &conf, opt.dhmlen );
1479 #endif
1480 
1481 #if defined(MBEDTLS_SSL_ALPN)
1482     if( opt.alpn_string != NULL )
1483         if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
1484         {
1485             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n",
1486                             ret );
1487             goto exit;
1488         }
1489 #endif
1490 
1491     mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
1492     mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
1493 
1494     mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
1495 
1496 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
1497     mbedtls_ssl_conf_session_tickets( &conf, opt.tickets );
1498 #endif
1499 
1500     if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
1501         mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
1502 
1503 #if defined(MBEDTLS_ARC4_C)
1504     if( opt.arc4 != DFL_ARC4 )
1505         mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 );
1506 #endif
1507 
1508     if( opt.allow_legacy != DFL_ALLOW_LEGACY )
1509         mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy );
1510 #if defined(MBEDTLS_SSL_RENEGOTIATION)
1511     mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation );
1512 #endif
1513 
1514 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1515     if( strcmp( opt.ca_path, "none" ) != 0 &&
1516         strcmp( opt.ca_file, "none" ) != 0 )
1517     {
1518         mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
1519     }
1520     if( strcmp( opt.crt_file, "none" ) != 0 &&
1521         strcmp( opt.key_file, "none" ) != 0 )
1522     {
1523         if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) ) != 0 )
1524         {
1525             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n",
1526                             ret );
1527             goto exit;
1528         }
1529     }
1530 #endif
1531 
1532 #if defined(MBEDTLS_ECP_C)
1533     if( opt.curves != NULL &&
1534         strcmp( opt.curves, "default" ) != 0 )
1535     {
1536         mbedtls_ssl_conf_curves( &conf, curve_list );
1537     }
1538 #endif
1539 
1540 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
1541     if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
1542                              (const unsigned char *) opt.psk_identity,
1543                              strlen( opt.psk_identity ) ) ) != 0 )
1544     {
1545         mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_psk returned %d\n\n",
1546                         ret );
1547         goto exit;
1548     }
1549 #endif
1550 
1551     if( opt.min_version != DFL_MIN_VERSION )
1552         mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3,
1553                                       opt.min_version );
1554 
1555     if( opt.max_version != DFL_MAX_VERSION )
1556         mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3,
1557                                       opt.max_version );
1558 
1559 #if defined(MBEDTLS_SSL_FALLBACK_SCSV)
1560     if( opt.fallback != DFL_FALLBACK )
1561         mbedtls_ssl_conf_fallback( &conf, opt.fallback );
1562 #endif
1563 
1564     if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
1565     {
1566         mbedtls_printf( " failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n",
1567                         -ret );
1568         goto exit;
1569     }
1570 
1571 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1572     if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
1573     {
1574         mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n",
1575                         ret );
1576         goto exit;
1577     }
1578 #endif
1579 
1580 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1581     if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
1582     {
1583         if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
1584                         (const unsigned char *) opt.ecjpake_pw,
1585                                         strlen( opt.ecjpake_pw ) ) ) != 0 )
1586         {
1587             mbedtls_printf( " failed\n  ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n",
1588                             ret );
1589             goto exit;
1590         }
1591     }
1592 #endif
1593 
1594     if( opt.nbio == 2 )
1595         mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
1596     else
1597         mbedtls_ssl_set_bio( &ssl, &server_fd,
1598                              mbedtls_net_send, mbedtls_net_recv,
1599                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
1600 
1601 #if defined(MBEDTLS_SSL_PROTO_DTLS)
1602     if( opt.dtls_mtu != DFL_DTLS_MTU )
1603         mbedtls_ssl_set_mtu( &ssl, opt.dtls_mtu );
1604 #endif
1605 
1606 #if defined(MBEDTLS_TIMING_C)
1607     mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
1608                                             mbedtls_timing_get_delay );
1609 #endif
1610 
1611 #if defined(MBEDTLS_ECP_RESTARTABLE)
1612     if( opt.ec_max_ops != DFL_EC_MAX_OPS )
1613         mbedtls_ecp_set_max_ops( opt.ec_max_ops );
1614 #endif
1615 
1616     mbedtls_printf( " ok\n" );
1617 
1618     /*
1619      * 4. Handshake
1620      */
1621     mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
1622     fflush( stdout );
1623 
1624     while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
1625     {
1626         if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1627             ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
1628             ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1629         {
1630             mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n",
1631                             -ret );
1632             if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
1633                 mbedtls_printf(
1634                     "    Unable to verify the server's certificate. "
1635                         "Either it is invalid,\n"
1636                     "    or you didn't set ca_file or ca_path "
1637                         "to an appropriate value.\n"
1638                     "    Alternatively, you may want to use "
1639                         "auth_mode=optional for testing purposes.\n" );
1640             mbedtls_printf( "\n" );
1641             goto exit;
1642         }
1643 
1644 #if defined(MBEDTLS_ECP_RESTARTABLE)
1645         if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1646             continue;
1647 #endif
1648 
1649         /* For event-driven IO, wait for socket to become available */
1650         if( opt.event == 1 /* level triggered IO */ )
1651         {
1652 #if defined(MBEDTLS_TIMING_C)
1653             ret = idle( &server_fd, &timer, ret );
1654 #else
1655             ret = idle( &server_fd, ret );
1656 #endif
1657             if( ret != 0 )
1658                 goto exit;
1659         }
1660     }
1661 
1662     mbedtls_printf( " ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n",
1663                     mbedtls_ssl_get_version( &ssl ),
1664                     mbedtls_ssl_get_ciphersuite( &ssl ) );
1665 
1666     if( ( ret = mbedtls_ssl_get_record_expansion( &ssl ) ) >= 0 )
1667         mbedtls_printf( "    [ Record expansion is %d ]\n", ret );
1668     else
1669         mbedtls_printf( "    [ Record expansion is unknown (compression) ]\n" );
1670 
1671 #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1672     mbedtls_printf( "    [ Maximum fragment length is %u ]\n",
1673                     (unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
1674 #endif
1675 
1676 #if defined(MBEDTLS_SSL_ALPN)
1677     if( opt.alpn_string != NULL )
1678     {
1679         const char *alp = mbedtls_ssl_get_alpn_protocol( &ssl );
1680         mbedtls_printf( "    [ Application Layer Protocol is %s ]\n",
1681                 alp ? alp : "(none)" );
1682     }
1683 #endif
1684 
1685     if( opt.reconnect != 0 )
1686     {
1687         mbedtls_printf("  . Saving session for reuse..." );
1688         fflush( stdout );
1689 
1690         if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
1691         {
1692             mbedtls_printf( " failed\n  ! mbedtls_ssl_get_session returned -0x%x\n\n",
1693                             -ret );
1694             goto exit;
1695         }
1696 
1697         mbedtls_printf( " ok\n" );
1698     }
1699 
1700 #if defined(MBEDTLS_X509_CRT_PARSE_C)
1701     /*
1702      * 5. Verify the server certificate
1703      */
1704     mbedtls_printf( "  . Verifying peer X.509 certificate..." );
1705 
1706     if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
1707     {
1708         char vrfy_buf[512];
1709 
1710         mbedtls_printf( " failed\n" );
1711 
1712         mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ),
1713                                       "  ! ", flags );
1714 
1715         mbedtls_printf( "%s\n", vrfy_buf );
1716     }
1717     else
1718         mbedtls_printf( " ok\n" );
1719 
1720     if( mbedtls_ssl_get_peer_cert( &ssl ) != NULL )
1721     {
1722         mbedtls_printf( "  . Peer certificate information    ...\n" );
1723         mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
1724                        mbedtls_ssl_get_peer_cert( &ssl ) );
1725         mbedtls_printf( "%s\n", buf );
1726     }
1727 #endif /* MBEDTLS_X509_CRT_PARSE_C */
1728 
1729 #if defined(MBEDTLS_SSL_RENEGOTIATION)
1730     if( opt.renegotiate )
1731     {
1732         /*
1733          * Perform renegotiation (this must be done when the server is waiting
1734          * for input from our side).
1735          */
1736         mbedtls_printf( "  . Performing renegotiation..." );
1737         fflush( stdout );
1738         while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
1739         {
1740             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1741                 ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
1742                 ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1743             {
1744                 mbedtls_printf( " failed\n  ! mbedtls_ssl_renegotiate returned %d\n\n",
1745                                 ret );
1746                 goto exit;
1747             }
1748 
1749 #if defined(MBEDTLS_ECP_RESTARTABLE)
1750             if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1751                 continue;
1752 #endif
1753 
1754             /* For event-driven IO, wait for socket to become available */
1755             if( opt.event == 1 /* level triggered IO */ )
1756             {
1757 #if defined(MBEDTLS_TIMING_C)
1758                 idle( &server_fd, &timer, ret );
1759 #else
1760                 idle( &server_fd, ret );
1761 #endif
1762             }
1763 
1764         }
1765         mbedtls_printf( " ok\n" );
1766     }
1767 #endif /* MBEDTLS_SSL_RENEGOTIATION */
1768 
1769     /*
1770      * 6. Write the GET request
1771      */
1772     retry_left = opt.max_resend;
1773 send_request:
1774     mbedtls_printf( "  > Write to server:" );
1775     fflush( stdout );
1776 
1777     len = mbedtls_snprintf( (char *) buf, sizeof( buf ) - 1, GET_REQUEST,
1778                             opt.request_page );
1779     tail_len = (int) strlen( GET_REQUEST_END );
1780 
1781     /* Add padding to GET request to reach opt.request_size in length */
1782     if( opt.request_size != DFL_REQUEST_SIZE &&
1783         len + tail_len < opt.request_size )
1784     {
1785         memset( buf + len, 'A', opt.request_size - len - tail_len );
1786         len += opt.request_size - len - tail_len;
1787     }
1788 
1789     strncpy( (char *) buf + len, GET_REQUEST_END, sizeof( buf ) - len - 1 );
1790     len += tail_len;
1791 
1792     /* Truncate if request size is smaller than the "natural" size */
1793     if( opt.request_size != DFL_REQUEST_SIZE &&
1794         len > opt.request_size )
1795     {
1796         len = opt.request_size;
1797 
1798         /* Still end with \r\n unless that's really not possible */
1799         if( len >= 2 ) buf[len - 2] = '\r';
1800         if( len >= 1 ) buf[len - 1] = '\n';
1801     }
1802 
1803     if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
1804     {
1805         written = 0;
1806         frags = 0;
1807 
1808         do
1809         {
1810             while( ( ret = mbedtls_ssl_write( &ssl, buf + written,
1811                                               len - written ) ) < 0 )
1812             {
1813                 if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1814                     ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
1815                     ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1816                 {
1817                     mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned -0x%x\n\n",
1818                                     -ret );
1819                     goto exit;
1820                 }
1821 
1822                 /* For event-driven IO, wait for socket to become available */
1823                 if( opt.event == 1 /* level triggered IO */ )
1824                 {
1825 #if defined(MBEDTLS_TIMING_C)
1826                     idle( &server_fd, &timer, ret );
1827 #else
1828                     idle( &server_fd, ret );
1829 #endif
1830                 }
1831             }
1832 
1833             frags++;
1834             written += ret;
1835         }
1836         while( written < len );
1837     }
1838     else /* Not stream, so datagram */
1839     {
1840         while( 1 )
1841         {
1842             ret = mbedtls_ssl_write( &ssl, buf, len );
1843 
1844 #if defined(MBEDTLS_ECP_RESTARTABLE)
1845             if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1846                 continue;
1847 #endif
1848 
1849             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1850                 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1851                 break;
1852 
1853             /* For event-driven IO, wait for socket to become available */
1854             if( opt.event == 1 /* level triggered IO */ )
1855             {
1856 #if defined(MBEDTLS_TIMING_C)
1857                 idle( &server_fd, &timer, ret );
1858 #else
1859                 idle( &server_fd, ret );
1860 #endif
1861             }
1862         }
1863 
1864         if( ret < 0 )
1865         {
1866             mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n",
1867                             ret );
1868             goto exit;
1869         }
1870 
1871         frags = 1;
1872         written = ret;
1873 
1874         if( written < len )
1875         {
1876             mbedtls_printf( " warning\n  ! request didn't fit into single datagram and "
1877                             "was truncated to size %u", (unsigned) written );
1878         }
1879     }
1880 
1881     buf[written] = '\0';
1882     mbedtls_printf( " %d bytes written in %d fragments\n\n%s\n",
1883                     written, frags, (char *) buf );
1884 
1885     /* Send a non-empty request if request_size == 0 */
1886     if ( len == 0 )
1887     {
1888         opt.request_size = DFL_REQUEST_SIZE;
1889         goto send_request;
1890     }
1891 
1892     /*
1893      * 7. Read the HTTP response
1894      */
1895     mbedtls_printf( "  < Read from server:" );
1896     fflush( stdout );
1897 
1898     /*
1899      * TLS and DTLS need different reading styles (stream vs datagram)
1900      */
1901     if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
1902     {
1903         do
1904         {
1905             len = sizeof( buf ) - 1;
1906             memset( buf, 0, sizeof( buf ) );
1907             ret = mbedtls_ssl_read( &ssl, buf, len );
1908 
1909 #if defined(MBEDTLS_ECP_RESTARTABLE)
1910             if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1911                 continue;
1912 #endif
1913 
1914             if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
1915                 ret == MBEDTLS_ERR_SSL_WANT_WRITE )
1916             {
1917                 /* For event-driven IO, wait for socket to become available */
1918                 if( opt.event == 1 /* level triggered IO */ )
1919                 {
1920 #if defined(MBEDTLS_TIMING_C)
1921                     idle( &server_fd, &timer, ret );
1922 #else
1923                     idle( &server_fd, ret );
1924 #endif
1925                 }
1926                 continue;
1927             }
1928 
1929             if( ret <= 0 )
1930             {
1931                 switch( ret )
1932                 {
1933                     case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
1934                         mbedtls_printf( " connection was closed gracefully\n" );
1935                         ret = 0;
1936                         goto close_notify;
1937 
1938                     case 0:
1939                     case MBEDTLS_ERR_NET_CONN_RESET:
1940                         mbedtls_printf( " connection was reset by peer\n" );
1941                         ret = 0;
1942                         goto reconnect;
1943 
1944                     default:
1945                         mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n",
1946                                         -ret );
1947                         goto exit;
1948                 }
1949             }
1950 
1951             len = ret;
1952             buf[len] = '\0';
1953             mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
1954 
1955             /* End of message should be detected according to the syntax of the
1956              * application protocol (eg HTTP), just use a dummy test here. */
1957             if( ret > 0 && buf[len-1] == '\n' )
1958             {
1959                 ret = 0;
1960                 break;
1961             }
1962         }
1963         while( 1 );
1964     }
1965     else /* Not stream, so datagram */
1966     {
1967         len = sizeof( buf ) - 1;
1968         memset( buf, 0, sizeof( buf ) );
1969 
1970         while( 1 )
1971         {
1972             ret = mbedtls_ssl_read( &ssl, buf, len );
1973 
1974 #if defined(MBEDTLS_ECP_RESTARTABLE)
1975             if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
1976                 continue;
1977 #endif
1978 
1979             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
1980                 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
1981                 break;
1982 
1983             /* For event-driven IO, wait for socket to become available */
1984             if( opt.event == 1 /* level triggered IO */ )
1985             {
1986 #if defined(MBEDTLS_TIMING_C)
1987                 idle( &server_fd, &timer, ret );
1988 #else
1989                 idle( &server_fd, ret );
1990 #endif
1991             }
1992         }
1993 
1994         if( ret <= 0 )
1995         {
1996             switch( ret )
1997             {
1998                 case MBEDTLS_ERR_SSL_TIMEOUT:
1999                     mbedtls_printf( " timeout\n" );
2000                     if( retry_left-- > 0 )
2001                         goto send_request;
2002                     goto exit;
2003 
2004                 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2005                     mbedtls_printf( " connection was closed gracefully\n" );
2006                     ret = 0;
2007                     goto close_notify;
2008 
2009                 default:
2010                     mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
2011                     goto exit;
2012             }
2013         }
2014 
2015         len = ret;
2016         buf[len] = '\0';
2017         mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
2018         ret = 0;
2019     }
2020 
2021     /*
2022      * 7b. Simulate hard reset and reconnect from same port?
2023      */
2024     if( opt.reconnect_hard != 0 )
2025     {
2026         opt.reconnect_hard = 0;
2027 
2028         mbedtls_printf( "  . Restarting connection from same port..." );
2029         fflush( stdout );
2030 
2031         if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
2032         {
2033             mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned -0x%x\n\n",
2034                             -ret );
2035             goto exit;
2036         }
2037 
2038         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
2039         {
2040             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
2041                 ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
2042                 ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2043             {
2044                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n",
2045                                 -ret );
2046                 goto exit;
2047             }
2048 
2049             /* For event-driven IO, wait for socket to become available */
2050             if( opt.event == 1 /* level triggered IO */ )
2051             {
2052 #if defined(MBEDTLS_TIMING_C)
2053                 idle( &server_fd, &timer, ret );
2054 #else
2055                 idle( &server_fd, ret );
2056 #endif
2057             }
2058         }
2059 
2060         mbedtls_printf( " ok\n" );
2061 
2062         goto send_request;
2063     }
2064 
2065     /*
2066      * 7c. Continue doing data exchanges?
2067      */
2068     if( --opt.exchanges > 0 )
2069         goto send_request;
2070 
2071     /*
2072      * 8. Done, cleanly close the connection
2073      */
2074 close_notify:
2075     mbedtls_printf( "  . Closing the connection..." );
2076     fflush( stdout );
2077 
2078     /*
2079      * Most of the time sending a close_notify before closing is the right
2080      * thing to do. However, when the server already knows how many messages
2081      * are expected and closes the connection by itself, this alert becomes
2082      * redundant. Sometimes with DTLS this redundancy becomes a problem by
2083      * leading to a race condition where the server might close the connection
2084      * before seeing the alert, and since UDP is connection-less when the
2085      * alert arrives it will be seen as a new connection, which will fail as
2086      * the alert is clearly not a valid ClientHello. This may cause spurious
2087      * failures in tests that use DTLS and resumption with ssl_server2 in
2088      * ssl-opt.sh, avoided by enabling skip_close_notify client-side.
2089      */
2090     if( opt.skip_close_notify == 0 )
2091     {
2092         /* No error checking, the connection might be closed already */
2093         do ret = mbedtls_ssl_close_notify( &ssl );
2094         while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
2095         ret = 0;
2096     }
2097 
2098     mbedtls_printf( " done\n" );
2099 
2100     /*
2101      * 9. Reconnect?
2102      */
2103 reconnect:
2104     if( opt.reconnect != 0 )
2105     {
2106         --opt.reconnect;
2107 
2108         mbedtls_net_free( &server_fd );
2109 
2110 #if defined(MBEDTLS_TIMING_C)
2111         if( opt.reco_delay > 0 )
2112             mbedtls_net_usleep( 1000000 * opt.reco_delay );
2113 #endif
2114 
2115         mbedtls_printf( "  . Reconnecting with saved session..." );
2116 
2117         if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
2118         {
2119             mbedtls_printf( " failed\n  ! mbedtls_ssl_session_reset returned -0x%x\n\n",
2120                             -ret );
2121             goto exit;
2122         }
2123 
2124         if( ( ret = mbedtls_ssl_set_session( &ssl, &saved_session ) ) != 0 )
2125         {
2126             mbedtls_printf( " failed\n  ! mbedtls_ssl_conf_session returned %d\n\n",
2127                             ret );
2128             goto exit;
2129         }
2130 
2131         if( ( ret = mbedtls_net_connect( &server_fd,
2132                         opt.server_addr, opt.server_port,
2133                         opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
2134                         MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) != 0 )
2135         {
2136             mbedtls_printf( " failed\n  ! mbedtls_net_connect returned -0x%x\n\n",
2137                             -ret );
2138             goto exit;
2139         }
2140 
2141         if( opt.nbio > 0 )
2142             ret = mbedtls_net_set_nonblock( &server_fd );
2143         else
2144             ret = mbedtls_net_set_block( &server_fd );
2145         if( ret != 0 )
2146         {
2147             mbedtls_printf( " failed\n  ! net_set_(non)block() returned -0x%x\n\n",
2148                             -ret );
2149             goto exit;
2150         }
2151 
2152         while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
2153         {
2154             if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
2155                 ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
2156                 ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2157             {
2158                 mbedtls_printf( " failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n",
2159                                 -ret );
2160                 goto exit;
2161             }
2162         }
2163 
2164         mbedtls_printf( " ok\n" );
2165 
2166         goto send_request;
2167     }
2168 
2169     /*
2170      * Cleanup and exit
2171      */
2172 exit:
2173 #ifdef MBEDTLS_ERROR_C
2174     if( ret != 0 )
2175     {
2176         char error_buf[100];
2177         mbedtls_strerror( ret, error_buf, 100 );
2178         mbedtls_printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
2179     }
2180 #endif
2181 
2182     mbedtls_net_free( &server_fd );
2183 
2184 #if defined(MBEDTLS_X509_CRT_PARSE_C)
2185     mbedtls_x509_crt_free( &clicert );
2186     mbedtls_x509_crt_free( &cacert );
2187     mbedtls_pk_free( &pkey );
2188 #endif
2189     mbedtls_ssl_session_free( &saved_session );
2190     mbedtls_ssl_free( &ssl );
2191     mbedtls_ssl_config_free( &conf );
2192     mbedtls_ctr_drbg_free( &ctr_drbg );
2193     mbedtls_entropy_free( &entropy );
2194 
2195 #if defined(_WIN32)
2196     mbedtls_printf( "  + Press Enter to exit this program.\n" );
2197     fflush( stdout ); getchar();
2198 #endif
2199 
2200     // Shell can not handle large exit numbers -> 1 for errors
2201     if( ret < 0 )
2202         ret = 1;
2203 
2204     mbedtls_exit( ret );
2205 }
2206 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
2207           MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
2208           MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */
2209