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