blob: b586a7008406be648b44ef52890eb29dcd8b6005 [file] [log] [blame]
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001/*
2 * SSL client with options
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Paul Bakkerb60b95f2012-09-25 09:05:17 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb60b95f2012-09-25 09:05:17 +000020 */
21
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000023#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020024#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020026#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/platform.h"
Rich Evansf90016a2015-01-19 14:26:37 +000030#else
Manuel Pégourié-Gonnard8a4d5712014-06-24 14:19:59 +020031#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#define mbedtls_free free
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020033#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#define mbedtls_fprintf fprintf
35#define mbedtls_printf printf
Rich Evans18b78c72015-02-11 14:06:19 +000036#endif
Manuel Pégourié-Gonnard8a4d5712014-06-24 14:19:59 +020037
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +020038#if !defined(MBEDTLS_ENTROPY_C) || \
39 !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_SRV_C) || \
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +020040 !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_CTR_DRBG_C)
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +020041int main( void )
42{
43 mbedtls_printf("MBEDTLS_ENTROPY_C and/or "
44 "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +020045 "MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined.\n");
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +020046 return( 0 );
47}
48#else
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +010049
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/net.h"
51#include "mbedtls/ssl.h"
52#include "mbedtls/entropy.h"
53#include "mbedtls/ctr_drbg.h"
54#include "mbedtls/certs.h"
55#include "mbedtls/x509.h"
56#include "mbedtls/error.h"
57#include "mbedtls/debug.h"
Manuel Pégourié-Gonnard56273da2015-05-26 12:19:45 +020058#include "mbedtls/timing.h"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000059
Rich Evans18b78c72015-02-11 14:06:19 +000060#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
Rich Evans18b78c72015-02-11 14:06:19 +000063
64#if !defined(_WIN32)
65#include <signal.h>
66#endif
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_SSL_CACHE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/ssl_cache.h"
Paul Bakker0a597072012-09-25 21:55:46 +000070#endif
71
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +020072#if defined(MBEDTLS_SSL_TICKET_C)
73#include "mbedtls/ssl_ticket.h"
74#endif
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#if defined(MBEDTLS_SSL_COOKIE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000077#include "mbedtls/ssl_cookie.h"
Manuel Pégourié-Gonnard232edd42014-07-23 16:56:27 +020078#endif
79
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000081#include "mbedtls/memory_buffer_alloc.h"
Paul Bakker82024bf2013-07-04 11:52:32 +020082#endif
83
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +020084#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_FS_IO)
85#define SNI_OPTION
86#endif
87
88#if defined(_WIN32)
89#include <windows.h>
90#endif
91
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +010092#define DFL_SERVER_ADDR NULL
Manuel Pégourié-Gonnardc0d74942015-06-23 12:30:57 +020093#define DFL_SERVER_PORT "4433"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000094#define DFL_DEBUG_LEVEL 0
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +010095#define DFL_NBIO 0
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +020096#define DFL_READ_TIMEOUT 0
Paul Bakkerb60b95f2012-09-25 09:05:17 +000097#define DFL_CA_FILE ""
98#define DFL_CA_PATH ""
99#define DFL_CRT_FILE ""
100#define DFL_KEY_FILE ""
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200101#define DFL_CRT_FILE2 ""
102#define DFL_KEY_FILE2 ""
Paul Bakkerfbb17802013-04-17 19:10:21 +0200103#define DFL_PSK ""
104#define DFL_PSK_IDENTITY "Client_identity"
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200105#define DFL_ECJPAKE_PW NULL
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200106#define DFL_PSK_LIST NULL
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000107#define DFL_FORCE_CIPHER 0
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +0200108#define DFL_VERSION_SUITES NULL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109#define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED
Manuel Pégourié-Gonnard85d915b2014-11-03 20:10:36 +0100110#define DFL_ALLOW_LEGACY -2
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100111#define DFL_RENEGOTIATE 0
Manuel Pégourié-Gonnardfae355e2014-07-04 14:32:27 +0200112#define DFL_RENEGO_DELAY -2
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +0100113#define DFL_RENEGO_PERIOD -1
Manuel Pégourié-Gonnard67686c42014-08-15 11:17:27 +0200114#define DFL_EXCHANGES 1
Manuel Pégourié-Gonnard8c8be1e2015-03-31 14:21:11 +0200115#define DFL_MIN_VERSION -1
Paul Bakkerc1516be2013-06-29 16:01:32 +0200116#define DFL_MAX_VERSION -1
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +0000117#define DFL_ARC4 -1
Manuel Pégourié-Gonnardfa44f202015-03-27 17:52:25 +0100118#define DFL_AUTH_MODE -1
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119#define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +0100120#define DFL_TRUNC_HMAC -1
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121#define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +0200122#define DFL_TICKET_TIMEOUT 86400
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100123#define DFL_CACHE_MAX -1
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100124#define DFL_CACHE_TIMEOUT -1
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100125#define DFL_SNI NULL
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200126#define DFL_ALPN_STRING NULL
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200127#define DFL_DHM_FILE NULL
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128#define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +0200129#define DFL_COOKIES 1
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +0200130#define DFL_ANTI_REPLAY -1
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200131#define DFL_HS_TO_MIN 0
132#define DFL_HS_TO_MAX 0
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +0200133#define DFL_BADMAC_LIMIT -1
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200134#define DFL_EXTENDED_MS -1
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100135#define DFL_ETM -1
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000136
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200137#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
138 "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
139 "03-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
140 "04-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
141 "05-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
142 "06-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
143 "07-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah</p>\r\n"
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200144
Paul Bakker8e714d72013-07-18 11:05:13 +0200145/* Uncomment LONG_RESPONSE at the end of HTTP_RESPONSE to test sending longer
146 * packets (for fragmentation purposes) */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000147#define HTTP_RESPONSE \
148 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
Manuel Pégourié-Gonnard91699212015-01-22 16:26:39 +0000149 "<h2>mbed TLS Test Server</h2>\r\n" \
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200150 "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000151
Manuel Pégourié-Gonnard95c0a632014-06-11 18:32:36 +0200152/*
153 * Size of the basic I/O buffer. Able to hold our default response.
154 *
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 * You will need to adapt the mbedtls_ssl_get_bytes_avail() test in ssl-opt.sh
Manuel Pégourié-Gonnard95c0a632014-06-11 18:32:36 +0200156 * if you change this value to something outside the range <= 100 or > 500
157 */
Manuel Pégourié-Gonnarde7a3b102014-06-11 18:21:20 +0200158#define IO_BUF_LEN 200
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if defined(MBEDTLS_X509_CRT_PARSE_C)
161#if defined(MBEDTLS_FS_IO)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000162#define USAGE_IO \
Paul Bakker1f9d02d2012-11-20 10:30:55 +0100163 " ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \
164 " default: \"\" (pre-loaded)\n" \
165 " ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \
166 " default: \"\" (pre-loaded) (overrides ca_file)\n" \
167 " crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200168 " default: see note after key_file2\n" \
169 " key_file=%%s default: see note after key_file2\n" \
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200170 " crt_file2=%%s Your second cert and chain (in bottom to top order, top may be omitted)\n" \
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200171 " default: see note after key_file2\n" \
172 " key_file2=%%s default: see note below\n" \
173 " note: if neither crt_file/key_file nor crt_file2/key_file2 are used,\n" \
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200174 " preloaded certificate(s) and key(s) are used if available\n" \
175 " dhm_file=%%s File containing Diffie-Hellman parameters\n" \
176 " default: preloaded parameters\n"
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000177#else
178#define USAGE_IO \
Paul Bakkered27a042013-04-18 22:46:23 +0200179 "\n" \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 " No file operations available (MBEDTLS_FS_IO not defined)\n" \
Paul Bakkered27a042013-04-18 22:46:23 +0200181 "\n"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182#endif /* MBEDTLS_FS_IO */
Paul Bakkered27a042013-04-18 22:46:23 +0200183#else
184#define USAGE_IO ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkered27a042013-04-18 22:46:23 +0200186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkered27a042013-04-18 22:46:23 +0200188#define USAGE_PSK \
189 " psk=%%s default: \"\" (in hex, without 0x)\n" \
190 " psk_identity=%%s default: \"Client_identity\"\n"
191#else
192#define USAGE_PSK ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Paul Bakkera503a632013-08-14 13:48:06 +0200196#define USAGE_TICKETS \
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100197 " tickets=%%d default: 1 (enabled)\n" \
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +0200198 " ticket_timeout=%%d default: 86400 (one day)\n"
Paul Bakkera503a632013-08-14 13:48:06 +0200199#else
200#define USAGE_TICKETS ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201#endif /* MBEDTLS_SSL_SESSION_TICKETS */
Paul Bakkera503a632013-08-14 13:48:06 +0200202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#if defined(MBEDTLS_SSL_CACHE_C)
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100204#define USAGE_CACHE \
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100205 " cache_max=%%d default: cache default (50)\n" \
206 " cache_timeout=%%d default: cache default (1d)\n"
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100207#else
208#define USAGE_CACHE ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209#endif /* MBEDTLS_SSL_CACHE_C */
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100210
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +0200211#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100212#define USAGE_SNI \
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200213 " sni=%%s name1,cert1,key1,ca1,crl1,auth1[,...]\n" \
214 " default: disabled\n"
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100215#else
216#define USAGE_SNI ""
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +0200217#endif /* SNI_OPTION */
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100218
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Paul Bakker05decb22013-08-15 13:33:48 +0200220#define USAGE_MAX_FRAG_LEN \
221 " max_frag_len=%%d default: 16384 (tls default)\n" \
222 " options: 512, 1024, 2048, 4096\n"
223#else
224#define USAGE_MAX_FRAG_LEN ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
Paul Bakker05decb22013-08-15 13:33:48 +0200226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +0100228#define USAGE_TRUNC_HMAC \
229 " trunc_hmac=%%d default: library default\n"
230#else
231#define USAGE_TRUNC_HMAC ""
232#endif
233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200235#define USAGE_ALPN \
236 " alpn=%%s default: \"\" (disabled)\n" \
237 " example: spdy/1,http/1.1\n"
238#else
239#define USAGE_ALPN ""
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +0200243#define USAGE_COOKIES \
244 " cookies=0/1/-1 default: 1 (enabled)\n" \
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +0200245 " 0: disabled, -1: library default (broken)\n"
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +0200246#else
247#define USAGE_COOKIES ""
248#endif
249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +0200251#define USAGE_ANTI_REPLAY \
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +0200252 " anti_replay=0/1 default: (library default: enabled)\n"
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +0200253#else
254#define USAGE_ANTI_REPLAY ""
255#endif
256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +0200258#define USAGE_BADMAC_LIMIT \
259 " badmac_limit=%%d default: (library default: disabled)\n"
260#else
261#define USAGE_BADMAC_LIMIT ""
262#endif
263
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200265#define USAGE_DTLS \
266 " dtls=%%d default: 0 (TLS)\n" \
267 " hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
268 " range of DTLS handshake timeouts in millisecs\n"
269#else
270#define USAGE_DTLS ""
271#endif
272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200274#define USAGE_EMS \
275 " extended_ms=0/1 default: (library default: on)\n"
276#else
277#define USAGE_EMS ""
278#endif
279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100281#define USAGE_ETM \
282 " etm=0/1 default: (library default: on)\n"
283#else
284#define USAGE_ETM ""
285#endif
286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100288#define USAGE_RENEGO \
289 " renegotiation=%%d default: 0 (disabled)\n" \
290 " renegotiate=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +0100291 " renego_delay=%%d default: -2 (library default)\n" \
292 " renego_period=%%d default: (library default)\n"
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100293#else
294#define USAGE_RENEGO ""
295#endif
296
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200297#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
298#define USAGE_ECJPAKE \
299 " ecjpake_pw=%%s default: none (disabled)\n"
300#else
301#define USAGE_ECJPAKE ""
302#endif
303
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000304#define USAGE \
305 "\n usage: ssl_server2 param=<>...\n" \
306 "\n acceptable parameters:\n" \
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100307 " server_addr=%%d default: (all interfaces)\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000308 " server_port=%%d default: 4433\n" \
309 " debug_level=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +0100310 " nbio=%%d default: 0 (blocking I/O)\n" \
311 " options: 1 (non-blocking), 2 (added delays)\n" \
Manuel Pégourié-Gonnard22311ae2015-09-09 11:22:58 +0200312 " read_timeout=%%d default: 0 ms (no timeout)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100313 "\n" \
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200314 USAGE_DTLS \
315 USAGE_COOKIES \
316 USAGE_ANTI_REPLAY \
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +0200317 USAGE_BADMAC_LIMIT \
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200318 "\n" \
Manuel Pégourié-Gonnardee6139c2015-05-07 10:18:26 +0100319 " auth_mode=%%s default: (library default: none)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100320 " options: none, optional, required\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000321 USAGE_IO \
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100322 USAGE_SNI \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100323 "\n" \
324 USAGE_PSK \
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200325 USAGE_ECJPAKE \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100326 "\n" \
Manuel Pégourié-Gonnard85d915b2014-11-03 20:10:36 +0100327 " allow_legacy=%%d default: (library default: no)\n" \
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +0100328 USAGE_RENEGO \
Manuel Pégourié-Gonnard67686c42014-08-15 11:17:27 +0200329 " exchanges=%%d default: 1\n" \
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200330 "\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100331 USAGE_TICKETS \
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100332 USAGE_CACHE \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100333 USAGE_MAX_FRAG_LEN \
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +0100334 USAGE_TRUNC_HMAC \
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200335 USAGE_ALPN \
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200336 USAGE_EMS \
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100337 USAGE_ETM \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100338 "\n" \
Manuel Pégourié-Gonnardfa44f202015-03-27 17:52:25 +0100339 " arc4=%%d default: (library default: 0)\n" \
Manuel Pégourié-Gonnard8c8be1e2015-03-31 14:21:11 +0200340 " min_version=%%s default: (library default: tls1)\n" \
341 " max_version=%%s default: (library default: tls1_2)\n" \
Paul Bakkerc1516be2013-06-29 16:01:32 +0200342 " force_version=%%s default: \"\" (none)\n" \
Manuel Pégourié-Gonnard83218f12014-02-12 11:11:12 +0100343 " options: ssl3, tls1, tls1_1, tls1_2, dtls1, dtls1_2\n" \
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +0200344 "\n" \
345 " version_suites=a,b,c,d per-version ciphersuites\n" \
346 " in order from ssl3 to tls1_2\n" \
347 " default: all enabled\n" \
348 " force_ciphersuite=<name> default: all enabled\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000349 " acceptable ciphersuite names:\n"
350
Rich Evans85b05ec2015-02-12 11:37:29 +0000351/*
352 * global options
353 */
354struct options
355{
356 const char *server_addr; /* address on which the ssl service runs */
Manuel Pégourié-Gonnardc0d74942015-06-23 12:30:57 +0200357 const char *server_port; /* port on which the ssl service runs */
Rich Evans85b05ec2015-02-12 11:37:29 +0000358 int debug_level; /* level of debugging */
359 int nbio; /* should I/O be blocking? */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 uint32_t read_timeout; /* timeout on mbedtls_ssl_read() in milliseconds */
Rich Evans85b05ec2015-02-12 11:37:29 +0000361 const char *ca_file; /* the file with the CA certificate(s) */
362 const char *ca_path; /* the path with the CA certificate(s) reside */
363 const char *crt_file; /* the file with the server certificate */
364 const char *key_file; /* the file with the server key */
365 const char *crt_file2; /* the file with the 2nd server certificate */
366 const char *key_file2; /* the file with the 2nd server key */
367 const char *psk; /* the pre-shared key */
368 const char *psk_identity; /* the pre-shared key identity */
369 char *psk_list; /* list of PSK id/key pairs for callback */
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200370 const char *ecjpake_pw; /* the EC J-PAKE password */
Rich Evans85b05ec2015-02-12 11:37:29 +0000371 int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
372 const char *version_suites; /* per-version ciphersuites */
373 int renegotiation; /* enable / disable renegotiation */
374 int allow_legacy; /* allow legacy renegotiation */
375 int renegotiate; /* attempt renegotiation? */
376 int renego_delay; /* delay before enforcing renegotiation */
377 int renego_period; /* period for automatic renegotiation */
378 int exchanges; /* number of data exchanges */
379 int min_version; /* minimum protocol version accepted */
380 int max_version; /* maximum protocol version accepted */
381 int arc4; /* flag for arc4 suites support */
382 int auth_mode; /* verify mode for connection */
383 unsigned char mfl_code; /* code for maximum fragment length */
384 int trunc_hmac; /* accept truncated hmac? */
385 int tickets; /* enable / disable session tickets */
386 int ticket_timeout; /* session ticket lifetime */
387 int cache_max; /* max number of session cache entries */
388 int cache_timeout; /* expiration delay of session cache entries */
389 char *sni; /* string describing sni information */
390 const char *alpn_string; /* ALPN supported protocols */
391 const char *dhm_file; /* the file with the DH parameters */
392 int extended_ms; /* allow negotiation of extended MS? */
393 int etm; /* allow negotiation of encrypt-then-MAC? */
Manuel Pégourié-Gonnardd901d172015-02-16 18:37:53 +0000394 int transport; /* TLS or DTLS? */
395 int cookies; /* Use cookies for DTLS? -1 to break them */
396 int anti_replay; /* Use anti-replay for DTLS? -1 for default */
397 uint32_t hs_to_min; /* Initial value of DTLS handshake timer */
398 uint32_t hs_to_max; /* Max value of DTLS handshake timer */
399 int badmac_limit; /* Limit of records with bad MAC */
Rich Evans85b05ec2015-02-12 11:37:29 +0000400} opt;
401
Manuel Pégourié-Gonnard61ee3512015-06-23 17:35:03 +0200402static void my_debug( void *ctx, int level,
403 const char *file, int line,
404 const char *str )
Rich Evans85b05ec2015-02-12 11:37:29 +0000405{
Manuel Pégourié-Gonnard052f2882015-07-01 11:50:23 +0200406 const char *p, *basename;
Rich Evans85b05ec2015-02-12 11:37:29 +0000407
Manuel Pégourié-Gonnard052f2882015-07-01 11:50:23 +0200408 /* Extract basename from file */
409 for( p = basename = file; *p != '\0'; p++ )
410 if( *p == '/' || *p == '\\' )
411 basename = p + 1;
412
413 mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str );
Rich Evans85b05ec2015-02-12 11:37:29 +0000414 fflush( (FILE *) ctx );
415}
416
417/*
418 * Test recv/send functions that make sure each try returns
419 * WANT_READ/WANT_WRITE at least once before sucesseding
420 */
421static int my_recv( void *ctx, unsigned char *buf, size_t len )
422{
423 static int first_try = 1;
424 int ret;
425
426 if( first_try )
427 {
428 first_try = 0;
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100429 return( MBEDTLS_ERR_SSL_WANT_READ );
Rich Evans85b05ec2015-02-12 11:37:29 +0000430 }
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 ret = mbedtls_net_recv( ctx, buf, len );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100433 if( ret != MBEDTLS_ERR_SSL_WANT_READ )
Rich Evans85b05ec2015-02-12 11:37:29 +0000434 first_try = 1; /* Next call will be a new operation */
435 return( ret );
436}
437
438static int my_send( void *ctx, const unsigned char *buf, size_t len )
439{
440 static int first_try = 1;
441 int ret;
442
443 if( first_try )
444 {
445 first_try = 0;
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100446 return( MBEDTLS_ERR_SSL_WANT_WRITE );
Rich Evans85b05ec2015-02-12 11:37:29 +0000447 }
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 ret = mbedtls_net_send( ctx, buf, len );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100450 if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Rich Evans85b05ec2015-02-12 11:37:29 +0000451 first_try = 1; /* Next call will be a new operation */
452 return( ret );
453}
454
Manuel Pégourié-Gonnardfdee74b2014-06-10 15:15:06 +0200455/*
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200456 * Return authmode from string, or -1 on error
457 */
458static int get_auth_mode( const char *s )
459{
460 if( strcmp( s, "none" ) == 0 )
461 return( MBEDTLS_SSL_VERIFY_NONE );
462 if( strcmp( s, "optional" ) == 0 )
463 return( MBEDTLS_SSL_VERIFY_OPTIONAL );
464 if( strcmp( s, "required" ) == 0 )
465 return( MBEDTLS_SSL_VERIFY_REQUIRED );
466
467 return( -1 );
468}
469
470/*
Manuel Pégourié-Gonnardfdee74b2014-06-10 15:15:06 +0200471 * Used by sni_parse and psk_parse to handle coma-separated lists
472 */
473#define GET_ITEM( dst ) \
474 dst = p; \
475 while( *p != ',' ) \
476 if( ++p > end ) \
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000477 goto error; \
Manuel Pégourié-Gonnardfdee74b2014-06-10 15:15:06 +0200478 *p++ = '\0';
479
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +0200480#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100481typedef struct _sni_entry sni_entry;
482
483struct _sni_entry {
484 const char *name;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_x509_crt *cert;
486 mbedtls_pk_context *key;
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200487 mbedtls_x509_crt* ca;
488 mbedtls_x509_crl* crl;
489 int authmode;
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100490 sni_entry *next;
491};
492
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100493void sni_free( sni_entry *head )
494{
495 sni_entry *cur = head, *next;
496
497 while( cur != NULL )
498 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_x509_crt_free( cur->cert );
500 mbedtls_free( cur->cert );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 mbedtls_pk_free( cur->key );
503 mbedtls_free( cur->key );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100504
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200505 mbedtls_x509_crt_free( cur->ca );
506 mbedtls_free( cur->ca );
507
508 mbedtls_x509_crl_free( cur->crl );
509 mbedtls_free( cur->crl );
510
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100511 next = cur->next;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_free( cur );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100513 cur = next;
514 }
515}
516
517/*
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200518 * Parse a string of sextuples name1,crt1,key1,ca1,crl1,auth1[,...]
519 * into a usable sni_entry list. For ca1, crl1, auth1, the special value
520 * '-' means unset. If ca1 is unset, then crl1 is ignored too.
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000521 *
522 * Modifies the input string! This is not production quality!
523 */
524sni_entry *sni_parse( char *sni_string )
525{
526 sni_entry *cur = NULL, *new = NULL;
527 char *p = sni_string;
528 char *end = p;
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200529 char *crt_file, *key_file, *ca_file, *crl_file, *auth_str;
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000530
531 while( *end != '\0' )
532 ++end;
533 *end = ',';
534
535 while( p <= end )
536 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200537 if( ( new = mbedtls_calloc( 1, sizeof( sni_entry ) ) ) == NULL )
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000538 {
539 sni_free( cur );
540 return( NULL );
541 }
542
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200543 GET_ITEM( new->name );
544 GET_ITEM( crt_file );
545 GET_ITEM( key_file );
546 GET_ITEM( ca_file );
547 GET_ITEM( crl_file );
548 GET_ITEM( auth_str );
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000549
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200550 if( ( new->cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ) ) == NULL ||
551 ( new->key = mbedtls_calloc( 1, sizeof( mbedtls_pk_context ) ) ) == NULL )
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200552 goto error;
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 mbedtls_x509_crt_init( new->cert );
555 mbedtls_pk_init( new->key );
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 if( mbedtls_x509_crt_parse_file( new->cert, crt_file ) != 0 ||
558 mbedtls_pk_parse_keyfile( new->key, key_file, "" ) != 0 )
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000559 goto error;
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200560
561 if( strcmp( ca_file, "-" ) != 0 )
562 {
563 if( ( new->ca = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ) ) == NULL )
564 goto error;
565
566 mbedtls_x509_crt_init( new->ca );
567
568 if( mbedtls_x509_crt_parse_file( new->ca, ca_file ) != 0 )
569 goto error;
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000570 }
571
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200572 if( strcmp( crl_file, "-" ) != 0 )
573 {
574 if( ( new->crl = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) ) ) == NULL )
575 goto error;
576
577 mbedtls_x509_crl_init( new->crl );
578
579 if( mbedtls_x509_crl_parse_file( new->crl, crl_file ) != 0 )
580 goto error;
581 }
582
583 if( strcmp( auth_str, "-" ) != 0 )
584 {
585 if( ( new->authmode = get_auth_mode( auth_str ) ) < 0 )
586 goto error;
587 }
588 else
589 new->authmode = DFL_AUTH_MODE;
590
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000591 new->next = cur;
592 cur = new;
593 }
594
595 return( cur );
596
597error:
598 sni_free( new );
599 sni_free( cur );
600 return( NULL );
601}
602
603/*
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100604 * SNI callback.
605 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606int sni_callback( void *p_info, mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100607 const unsigned char *name, size_t name_len )
608{
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200609 const sni_entry *cur = (const sni_entry *) p_info;
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100610
611 while( cur != NULL )
612 {
613 if( name_len == strlen( cur->name ) &&
614 memcmp( name, cur->name, name_len ) == 0 )
615 {
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +0200616 if( cur->ca != NULL )
617 mbedtls_ssl_set_hs_ca_chain( ssl, cur->ca, cur->crl );
618
619 if( cur->authmode != DFL_AUTH_MODE )
620 mbedtls_ssl_set_hs_authmode( ssl, cur->authmode );
621
Manuel Pégourié-Gonnard1af6c852015-05-10 23:10:37 +0200622 return( mbedtls_ssl_set_hs_own_cert( ssl, cur->cert, cur->key ) );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100623 }
624
625 cur = cur->next;
626 }
627
628 return( -1 );
629}
630
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +0200631#endif /* SNI_OPTION */
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Manuel Pégourié-Gonnard9e271632014-06-09 19:06:00 +0200634
635#define HEX2NUM( c ) \
636 if( c >= '0' && c <= '9' ) \
637 c -= '0'; \
638 else if( c >= 'a' && c <= 'f' ) \
639 c -= 'a' - 10; \
640 else if( c >= 'A' && c <= 'F' ) \
641 c -= 'A' - 10; \
642 else \
643 return( -1 );
644
645/*
646 * Convert a hex string to bytes.
647 * Return 0 on success, -1 on error.
648 */
649int unhexify( unsigned char *output, const char *input, size_t *olen )
650{
651 unsigned char c;
652 size_t j;
653
654 *olen = strlen( input );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 if( *olen % 2 != 0 || *olen / 2 > MBEDTLS_PSK_MAX_LEN )
Manuel Pégourié-Gonnard9e271632014-06-09 19:06:00 +0200656 return( -1 );
657 *olen /= 2;
658
659 for( j = 0; j < *olen * 2; j += 2 )
660 {
661 c = input[j];
662 HEX2NUM( c );
663 output[ j / 2 ] = c << 4;
664
665 c = input[j + 1];
666 HEX2NUM( c );
667 output[ j / 2 ] |= c;
668 }
669
670 return( 0 );
671}
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200672
673typedef struct _psk_entry psk_entry;
674
675struct _psk_entry
676{
677 const char *name;
678 size_t key_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 unsigned char key[MBEDTLS_PSK_MAX_LEN];
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200680 psk_entry *next;
681};
682
683/*
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000684 * Free a list of psk_entry's
685 */
686void psk_free( psk_entry *head )
687{
688 psk_entry *next;
689
690 while( head != NULL )
691 {
692 next = head->next;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_free( head );
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000694 head = next;
695 }
696}
697
698/*
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200699 * Parse a string of pairs name1,key1[,name2,key2[,...]]
700 * into a usable psk_entry list.
701 *
702 * Modifies the input string! This is not production quality!
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200703 */
704psk_entry *psk_parse( char *psk_string )
705{
706 psk_entry *cur = NULL, *new = NULL;
707 char *p = psk_string;
708 char *end = p;
709 char *key_hex;
710
711 while( *end != '\0' )
712 ++end;
713 *end = ',';
714
715 while( p <= end )
716 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200717 if( ( new = mbedtls_calloc( 1, sizeof( psk_entry ) ) ) == NULL )
Manuel Pégourié-Gonnardb1990952015-02-18 09:32:06 +0000718 goto error;
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200719
720 memset( new, 0, sizeof( psk_entry ) );
721
Manuel Pégourié-Gonnardfdee74b2014-06-10 15:15:06 +0200722 GET_ITEM( new->name );
723 GET_ITEM( key_hex );
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200724
725 if( unhexify( new->key, key_hex, &new->key_len ) != 0 )
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000726 goto error;
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200727
728 new->next = cur;
729 cur = new;
730 }
731
732 return( cur );
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200733
Manuel Pégourié-Gonnard5c078e12015-02-14 13:56:39 +0000734error:
735 psk_free( new );
736 psk_free( cur );
737 return( 0 );
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200738}
739
740/*
741 * PSK callback
742 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743int psk_callback( void *p_info, mbedtls_ssl_context *ssl,
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200744 const unsigned char *name, size_t name_len )
745{
746 psk_entry *cur = (psk_entry *) p_info;
747
748 while( cur != NULL )
749 {
750 if( name_len == strlen( cur->name ) &&
751 memcmp( name, cur->name, name_len ) == 0 )
752 {
Manuel Pégourié-Gonnard4b682962015-05-07 15:59:54 +0100753 return( mbedtls_ssl_set_hs_psk( ssl, cur->key, cur->key_len ) );
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200754 }
755
756 cur = cur->next;
757 }
758
759 return( -1 );
760}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Manuel Pégourié-Gonnard9e271632014-06-09 19:06:00 +0200762
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200763static mbedtls_net_context listen_fd, client_fd;
Paul Bakkerbc3e54c2014-08-18 14:36:17 +0200764
765/* Interruption handler to ensure clean exit (for valgrind testing) */
766#if !defined(_WIN32)
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +0200767static int received_sigterm = 0;
768void term_handler( int sig )
769{
770 ((void) sig);
771 received_sigterm = 1;
Manuel Pégourié-Gonnard3d7d00a2015-06-30 15:55:03 +0200772 mbedtls_net_free( &listen_fd ); /* causes mbedtls_net_accept() to abort */
773 mbedtls_net_free( &client_fd ); /* causes net_read() to abort */
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +0200774}
Paul Bakkerc1283d32014-08-18 11:05:51 +0200775#endif
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +0200776
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000777int main( int argc, char *argv[] )
778{
Manuel Pégourié-Gonnard6a0017b2015-01-22 10:33:29 +0000779 int ret = 0, len, written, frags, exchanges_left;
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +0200780 int version_suites[4][2];
Manuel Pégourié-Gonnarde7a3b102014-06-11 18:21:20 +0200781 unsigned char buf[IO_BUF_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
783 unsigned char psk[MBEDTLS_PSK_MAX_LEN];
Paul Bakkerfbb17802013-04-17 19:10:21 +0200784 size_t psk_len = 0;
Paul Bakker9b7fb6f2014-06-12 23:01:43 +0200785 psk_entry *psk_info = NULL;
Paul Bakkered27a042013-04-18 22:46:23 +0200786#endif
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200787 const char *pers = "ssl_server2";
Manuel Pégourié-Gonnard336b8242014-07-22 17:57:43 +0200788 unsigned char client_ip[16] = { 0 };
Manuel Pégourié-Gonnard0b104b02015-05-14 21:52:40 +0200789 size_t cliip_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#if defined(MBEDTLS_SSL_COOKIE_C)
791 mbedtls_ssl_cookie_ctx cookie_ctx;
Manuel Pégourié-Gonnardd485d192014-07-23 14:56:15 +0200792#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 mbedtls_entropy_context entropy;
795 mbedtls_ctr_drbg_context ctr_drbg;
796 mbedtls_ssl_context ssl;
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200797 mbedtls_ssl_config conf;
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +0200798#if defined(MBEDTLS_TIMING_C)
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +0200799 mbedtls_timing_delay_context timer;
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +0200800#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +0100802 unsigned char renego_period[8] = { 0 };
803#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804#if defined(MBEDTLS_X509_CRT_PARSE_C)
Manuel Pégourié-Gonnarddb1cc762015-05-12 11:27:25 +0200805 uint32_t flags;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 mbedtls_x509_crt cacert;
807 mbedtls_x509_crt srvcert;
808 mbedtls_pk_context pkey;
809 mbedtls_x509_crt srvcert2;
810 mbedtls_pk_context pkey2;
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200811 int key_cert_init = 0, key_cert_init2 = 0;
Paul Bakkered27a042013-04-18 22:46:23 +0200812#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
814 mbedtls_dhm_context dhm;
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200815#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816#if defined(MBEDTLS_SSL_CACHE_C)
817 mbedtls_ssl_cache_context cache;
Paul Bakker0a597072012-09-25 21:55:46 +0000818#endif
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +0200819#if defined(MBEDTLS_SSL_SESSION_TICKETS)
820 mbedtls_ssl_ticket_context ticket_ctx;
821#endif
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +0200822#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100823 sni_entry *sni_info = NULL;
824#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200826 const char *alpn_list[10];
827#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Paul Bakker82024bf2013-07-04 11:52:32 +0200829 unsigned char alloc_buf[100000];
830#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000831
832 int i;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000833 char *p, *q;
834 const int *list;
835
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
837 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
Paul Bakker82024bf2013-07-04 11:52:32 +0200838#endif
839
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000840 /*
Manuel Pégourié-Gonnard3bd2aae2013-09-20 13:10:13 +0200841 * Make sure memory references are valid in case we exit early.
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000842 */
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200843 mbedtls_net_init( &client_fd );
844 mbedtls_net_init( &listen_fd );
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +0200845 mbedtls_ssl_init( &ssl );
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200846 mbedtls_ssl_config_init( &conf );
Manuel Pégourié-Gonnardec160c02015-04-28 22:52:30 +0200847 mbedtls_ctr_drbg_init( &ctr_drbg );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848#if defined(MBEDTLS_X509_CRT_PARSE_C)
849 mbedtls_x509_crt_init( &cacert );
850 mbedtls_x509_crt_init( &srvcert );
851 mbedtls_pk_init( &pkey );
852 mbedtls_x509_crt_init( &srvcert2 );
853 mbedtls_pk_init( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +0200854#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
856 mbedtls_dhm_init( &dhm );
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200857#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#if defined(MBEDTLS_SSL_CACHE_C)
859 mbedtls_ssl_cache_init( &cache );
Paul Bakker0a597072012-09-25 21:55:46 +0000860#endif
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +0200861#if defined(MBEDTLS_SSL_SESSION_TICKETS)
862 mbedtls_ssl_ticket_init( &ticket_ctx );
863#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864#if defined(MBEDTLS_SSL_ALPN)
Paul Bakker525f8752014-05-01 10:58:57 +0200865 memset( (void *) alpn_list, 0, sizeof( alpn_list ) );
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200866#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867#if defined(MBEDTLS_SSL_COOKIE_C)
868 mbedtls_ssl_cookie_init( &cookie_ctx );
Manuel Pégourié-Gonnardd485d192014-07-23 14:56:15 +0200869#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000870
Paul Bakkerc1283d32014-08-18 11:05:51 +0200871#if !defined(_WIN32)
Manuel Pégourié-Gonnard403a86f2014-11-17 12:46:49 +0100872 /* Abort cleanly on SIGTERM and SIGINT */
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +0200873 signal( SIGTERM, term_handler );
Manuel Pégourié-Gonnard403a86f2014-11-17 12:46:49 +0100874 signal( SIGINT, term_handler );
Paul Bakkerc1283d32014-08-18 11:05:51 +0200875#endif
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +0200876
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000877 if( argc == 0 )
878 {
879 usage:
880 if( ret == 0 )
881 ret = 1;
882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_printf( USAGE );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000884
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 list = mbedtls_ssl_list_ciphersuites();
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000886 while( *list )
887 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_printf(" %-42s", mbedtls_ssl_get_ciphersuite_name( *list ) );
Paul Bakkered27a042013-04-18 22:46:23 +0200889 list++;
890 if( !*list )
891 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name( *list ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000893 list++;
894 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 mbedtls_printf("\n");
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000896 goto exit;
897 }
898
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100899 opt.server_addr = DFL_SERVER_ADDR;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000900 opt.server_port = DFL_SERVER_PORT;
901 opt.debug_level = DFL_DEBUG_LEVEL;
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +0100902 opt.nbio = DFL_NBIO;
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +0200903 opt.read_timeout = DFL_READ_TIMEOUT;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000904 opt.ca_file = DFL_CA_FILE;
905 opt.ca_path = DFL_CA_PATH;
906 opt.crt_file = DFL_CRT_FILE;
907 opt.key_file = DFL_KEY_FILE;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200908 opt.crt_file2 = DFL_CRT_FILE2;
909 opt.key_file2 = DFL_KEY_FILE2;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200910 opt.psk = DFL_PSK;
911 opt.psk_identity = DFL_PSK_IDENTITY;
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200912 opt.psk_list = DFL_PSK_LIST;
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200913 opt.ecjpake_pw = DFL_ECJPAKE_PW;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000914 opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +0200915 opt.version_suites = DFL_VERSION_SUITES;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000916 opt.renegotiation = DFL_RENEGOTIATION;
917 opt.allow_legacy = DFL_ALLOW_LEGACY;
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100918 opt.renegotiate = DFL_RENEGOTIATE;
Manuel Pégourié-Gonnardfae355e2014-07-04 14:32:27 +0200919 opt.renego_delay = DFL_RENEGO_DELAY;
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +0100920 opt.renego_period = DFL_RENEGO_PERIOD;
Manuel Pégourié-Gonnard67686c42014-08-15 11:17:27 +0200921 opt.exchanges = DFL_EXCHANGES;
Paul Bakker1d29fb52012-09-28 13:28:45 +0000922 opt.min_version = DFL_MIN_VERSION;
Paul Bakkerc1516be2013-06-29 16:01:32 +0200923 opt.max_version = DFL_MAX_VERSION;
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +0100924 opt.arc4 = DFL_ARC4;
Paul Bakker91ebfb52012-11-23 14:04:08 +0100925 opt.auth_mode = DFL_AUTH_MODE;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200926 opt.mfl_code = DFL_MFL_CODE;
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +0100927 opt.trunc_hmac = DFL_TRUNC_HMAC;
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200928 opt.tickets = DFL_TICKETS;
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +0100929 opt.ticket_timeout = DFL_TICKET_TIMEOUT;
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100930 opt.cache_max = DFL_CACHE_MAX;
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +0100931 opt.cache_timeout = DFL_CACHE_TIMEOUT;
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +0100932 opt.sni = DFL_SNI;
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +0200933 opt.alpn_string = DFL_ALPN_STRING;
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200934 opt.dhm_file = DFL_DHM_FILE;
Manuel Pégourié-Gonnarde29fd4b2014-02-06 14:02:55 +0100935 opt.transport = DFL_TRANSPORT;
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +0200936 opt.cookies = DFL_COOKIES;
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +0200937 opt.anti_replay = DFL_ANTI_REPLAY;
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +0200938 opt.hs_to_min = DFL_HS_TO_MIN;
939 opt.hs_to_max = DFL_HS_TO_MAX;
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +0200940 opt.badmac_limit = DFL_BADMAC_LIMIT;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +0200941 opt.extended_ms = DFL_EXTENDED_MS;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +0100942 opt.etm = DFL_ETM;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000943
944 for( i = 1; i < argc; i++ )
945 {
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000946 p = argv[i];
947 if( ( q = strchr( p, '=' ) ) == NULL )
948 goto usage;
949 *q++ = '\0';
950
951 if( strcmp( p, "server_port" ) == 0 )
Manuel Pégourié-Gonnardc0d74942015-06-23 12:30:57 +0200952 opt.server_port = q;
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100953 else if( strcmp( p, "server_addr" ) == 0 )
954 opt.server_addr = q;
Manuel Pégourié-Gonnarde29fd4b2014-02-06 14:02:55 +0100955 else if( strcmp( p, "dtls" ) == 0 )
956 {
957 int t = atoi( q );
958 if( t == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 opt.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
Manuel Pégourié-Gonnarde29fd4b2014-02-06 14:02:55 +0100960 else if( t == 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
Manuel Pégourié-Gonnarde29fd4b2014-02-06 14:02:55 +0100962 else
963 goto usage;
964 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000965 else if( strcmp( p, "debug_level" ) == 0 )
966 {
967 opt.debug_level = atoi( q );
968 if( opt.debug_level < 0 || opt.debug_level > 65535 )
969 goto usage;
970 }
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +0100971 else if( strcmp( p, "nbio" ) == 0 )
972 {
973 opt.nbio = atoi( q );
974 if( opt.nbio < 0 || opt.nbio > 2 )
975 goto usage;
976 }
Manuel Pégourié-Gonnard6b651412014-10-01 18:29:03 +0200977 else if( strcmp( p, "read_timeout" ) == 0 )
978 opt.read_timeout = atoi( q );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000979 else if( strcmp( p, "ca_file" ) == 0 )
980 opt.ca_file = q;
981 else if( strcmp( p, "ca_path" ) == 0 )
982 opt.ca_path = q;
983 else if( strcmp( p, "crt_file" ) == 0 )
984 opt.crt_file = q;
985 else if( strcmp( p, "key_file" ) == 0 )
986 opt.key_file = q;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200987 else if( strcmp( p, "crt_file2" ) == 0 )
988 opt.crt_file2 = q;
989 else if( strcmp( p, "key_file2" ) == 0 )
990 opt.key_file2 = q;
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +0200991 else if( strcmp( p, "dhm_file" ) == 0 )
992 opt.dhm_file = q;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200993 else if( strcmp( p, "psk" ) == 0 )
994 opt.psk = q;
995 else if( strcmp( p, "psk_identity" ) == 0 )
996 opt.psk_identity = q;
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +0200997 else if( strcmp( p, "psk_list" ) == 0 )
998 opt.psk_list = q;
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +0200999 else if( strcmp( p, "ecjpake_pw" ) == 0 )
1000 opt.ecjpake_pw = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001001 else if( strcmp( p, "force_ciphersuite" ) == 0 )
1002 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001003 opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id( q );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001004
Manuel Pégourié-Gonnard8de259b2014-06-11 14:19:06 +02001005 if( opt.force_ciphersuite[0] == 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001006 {
1007 ret = 2;
1008 goto usage;
1009 }
1010 opt.force_ciphersuite[1] = 0;
1011 }
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001012 else if( strcmp( p, "version_suites" ) == 0 )
1013 opt.version_suites = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001014 else if( strcmp( p, "renegotiation" ) == 0 )
1015 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 opt.renegotiation = (atoi( q )) ? MBEDTLS_SSL_RENEGOTIATION_ENABLED :
1017 MBEDTLS_SSL_RENEGOTIATION_DISABLED;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001018 }
1019 else if( strcmp( p, "allow_legacy" ) == 0 )
1020 {
Manuel Pégourié-Gonnard85d915b2014-11-03 20:10:36 +01001021 switch( atoi( q ) )
1022 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 case -1: opt.allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE; break;
1024 case 0: opt.allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION; break;
1025 case 1: opt.allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION; break;
Manuel Pégourié-Gonnard85d915b2014-11-03 20:10:36 +01001026 default: goto usage;
1027 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001028 }
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +01001029 else if( strcmp( p, "renegotiate" ) == 0 )
1030 {
1031 opt.renegotiate = atoi( q );
1032 if( opt.renegotiate < 0 || opt.renegotiate > 1 )
1033 goto usage;
1034 }
Manuel Pégourié-Gonnardfae355e2014-07-04 14:32:27 +02001035 else if( strcmp( p, "renego_delay" ) == 0 )
1036 {
1037 opt.renego_delay = atoi( q );
1038 }
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +01001039 else if( strcmp( p, "renego_period" ) == 0 )
1040 {
1041 opt.renego_period = atoi( q );
1042 if( opt.renego_period < 2 || opt.renego_period > 255 )
1043 goto usage;
1044 }
Manuel Pégourié-Gonnard67686c42014-08-15 11:17:27 +02001045 else if( strcmp( p, "exchanges" ) == 0 )
1046 {
1047 opt.exchanges = atoi( q );
Manuel Pégourié-Gonnard6a2bc232014-10-09 15:33:13 +02001048 if( opt.exchanges < 0 )
Manuel Pégourié-Gonnard67686c42014-08-15 11:17:27 +02001049 goto usage;
1050 }
Paul Bakker1d29fb52012-09-28 13:28:45 +00001051 else if( strcmp( p, "min_version" ) == 0 )
1052 {
1053 if( strcmp( q, "ssl3" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
Paul Bakker1d29fb52012-09-28 13:28:45 +00001055 else if( strcmp( q, "tls1" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
Manuel Pégourié-Gonnard83218f12014-02-12 11:11:12 +01001057 else if( strcmp( q, "tls1_1" ) == 0 ||
1058 strcmp( q, "dtls1" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
Manuel Pégourié-Gonnard83218f12014-02-12 11:11:12 +01001060 else if( strcmp( q, "tls1_2" ) == 0 ||
1061 strcmp( q, "dtls1_2" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
Paul Bakker1d29fb52012-09-28 13:28:45 +00001063 else
1064 goto usage;
1065 }
Paul Bakkerc1516be2013-06-29 16:01:32 +02001066 else if( strcmp( p, "max_version" ) == 0 )
1067 {
1068 if( strcmp( q, "ssl3" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001070 else if( strcmp( q, "tls1" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
Manuel Pégourié-Gonnard83218f12014-02-12 11:11:12 +01001072 else if( strcmp( q, "tls1_1" ) == 0 ||
1073 strcmp( q, "dtls1" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
Manuel Pégourié-Gonnard83218f12014-02-12 11:11:12 +01001075 else if( strcmp( q, "tls1_2" ) == 0 ||
1076 strcmp( q, "dtls1_2" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001078 else
1079 goto usage;
1080 }
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001081 else if( strcmp( p, "arc4" ) == 0 )
1082 {
1083 switch( atoi( q ) )
1084 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 case 0: opt.arc4 = MBEDTLS_SSL_ARC4_DISABLED; break;
1086 case 1: opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED; break;
Manuel Pégourié-Gonnardbd47a582015-01-12 13:43:29 +01001087 default: goto usage;
1088 }
1089 }
Paul Bakkerc1516be2013-06-29 16:01:32 +02001090 else if( strcmp( p, "force_version" ) == 0 )
1091 {
1092 if( strcmp( q, "ssl3" ) == 0 )
1093 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_0;
1095 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_0;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001096 }
1097 else if( strcmp( q, "tls1" ) == 0 )
1098 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_1;
1100 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_1;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001101 }
Manuel Pégourié-Gonnardfe3f73b2014-03-26 12:16:44 +01001102 else if( strcmp( q, "tls1_1" ) == 0 )
Paul Bakkerc1516be2013-06-29 16:01:32 +02001103 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
1105 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001106 }
Manuel Pégourié-Gonnardfe3f73b2014-03-26 12:16:44 +01001107 else if( strcmp( q, "tls1_2" ) == 0 )
Paul Bakkerc1516be2013-06-29 16:01:32 +02001108 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
1110 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
Paul Bakkerc1516be2013-06-29 16:01:32 +02001111 }
Manuel Pégourié-Gonnardfe3f73b2014-03-26 12:16:44 +01001112 else if( strcmp( q, "dtls1" ) == 0 )
1113 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
1115 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_2;
1116 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
Manuel Pégourié-Gonnardfe3f73b2014-03-26 12:16:44 +01001117 }
1118 else if( strcmp( q, "dtls1_2" ) == 0 )
1119 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_3;
1121 opt.max_version = MBEDTLS_SSL_MINOR_VERSION_3;
1122 opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
Manuel Pégourié-Gonnardfe3f73b2014-03-26 12:16:44 +01001123 }
Paul Bakkerc1516be2013-06-29 16:01:32 +02001124 else
1125 goto usage;
1126 }
Paul Bakker91ebfb52012-11-23 14:04:08 +01001127 else if( strcmp( p, "auth_mode" ) == 0 )
1128 {
Manuel Pégourié-Gonnard4d6f1782015-06-19 14:40:39 +02001129 if( ( opt.auth_mode = get_auth_mode( q ) ) < 0 )
Paul Bakker91ebfb52012-11-23 14:04:08 +01001130 goto usage;
1131 }
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001132 else if( strcmp( p, "max_frag_len" ) == 0 )
1133 {
1134 if( strcmp( q, "512" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001136 else if( strcmp( q, "1024" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_1024;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001138 else if( strcmp( q, "2048" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_2048;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001140 else if( strcmp( q, "4096" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_4096;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001142 else
1143 goto usage;
1144 }
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001145 else if( strcmp( p, "alpn" ) == 0 )
1146 {
1147 opt.alpn_string = q;
1148 }
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +01001149 else if( strcmp( p, "trunc_hmac" ) == 0 )
1150 {
1151 switch( atoi( q ) )
1152 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153 case 0: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED; break;
1154 case 1: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; break;
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +01001155 default: goto usage;
1156 }
1157 }
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001158 else if( strcmp( p, "extended_ms" ) == 0 )
1159 {
1160 switch( atoi( q ) )
1161 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162 case 0: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED; break;
1163 case 1: opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; break;
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001164 default: goto usage;
1165 }
1166 }
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001167 else if( strcmp( p, "etm" ) == 0 )
1168 {
1169 switch( atoi( q ) )
1170 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171 case 0: opt.etm = MBEDTLS_SSL_ETM_DISABLED; break;
1172 case 1: opt.etm = MBEDTLS_SSL_ETM_ENABLED; break;
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001173 default: goto usage;
1174 }
1175 }
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001176 else if( strcmp( p, "tickets" ) == 0 )
1177 {
1178 opt.tickets = atoi( q );
1179 if( opt.tickets < 0 || opt.tickets > 1 )
1180 goto usage;
1181 }
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +01001182 else if( strcmp( p, "ticket_timeout" ) == 0 )
1183 {
1184 opt.ticket_timeout = atoi( q );
1185 if( opt.ticket_timeout < 0 )
1186 goto usage;
1187 }
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +01001188 else if( strcmp( p, "cache_max" ) == 0 )
1189 {
1190 opt.cache_max = atoi( q );
1191 if( opt.cache_max < 0 )
1192 goto usage;
1193 }
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +01001194 else if( strcmp( p, "cache_timeout" ) == 0 )
1195 {
1196 opt.cache_timeout = atoi( q );
1197 if( opt.cache_timeout < 0 )
1198 goto usage;
1199 }
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001200 else if( strcmp( p, "cookies" ) == 0 )
1201 {
1202 opt.cookies = atoi( q );
1203 if( opt.cookies < -1 || opt.cookies > 1)
1204 goto usage;
1205 }
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02001206 else if( strcmp( p, "anti_replay" ) == 0 )
1207 {
1208 opt.anti_replay = atoi( q );
1209 if( opt.anti_replay < 0 || opt.anti_replay > 1)
1210 goto usage;
1211 }
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +02001212 else if( strcmp( p, "badmac_limit" ) == 0 )
1213 {
1214 opt.badmac_limit = atoi( q );
1215 if( opt.badmac_limit < 0 )
1216 goto usage;
1217 }
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +02001218 else if( strcmp( p, "hs_timeout" ) == 0 )
1219 {
1220 if( ( p = strchr( q, '-' ) ) == NULL )
1221 goto usage;
1222 *p++ = '\0';
1223 opt.hs_to_min = atoi( q );
1224 opt.hs_to_max = atoi( p );
1225 if( opt.hs_to_min == 0 || opt.hs_to_max < opt.hs_to_min )
1226 goto usage;
1227 }
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001228 else if( strcmp( p, "sni" ) == 0 )
1229 {
1230 opt.sni = q;
1231 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001232 else
1233 goto usage;
1234 }
1235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236#if defined(MBEDTLS_DEBUG_C)
1237 mbedtls_debug_set_threshold( opt.debug_level );
Paul Bakkerc73079a2014-04-25 16:34:30 +02001238#endif
1239
Paul Bakkerc1516be2013-06-29 16:01:32 +02001240 if( opt.force_ciphersuite[0] > 0 )
1241 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
1243 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
Paul Bakkerc1516be2013-06-29 16:01:32 +02001244
Paul Bakker5b55b792013-07-19 13:43:43 +02001245 if( opt.max_version != -1 &&
1246 ciphersuite_info->min_minor_ver > opt.max_version )
1247 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
Paul Bakker5b55b792013-07-19 13:43:43 +02001249 ret = 2;
1250 goto usage;
1251 }
1252 if( opt.min_version != -1 &&
Paul Bakkerc1516be2013-06-29 16:01:32 +02001253 ciphersuite_info->max_minor_ver < opt.min_version )
1254 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001255 mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
Paul Bakkerc1516be2013-06-29 16:01:32 +02001256 ret = 2;
1257 goto usage;
1258 }
Manuel Pégourié-Gonnard798f15a2014-03-26 18:12:04 +01001259
1260 /* If we select a version that's not supported by
1261 * this suite, then there will be no common ciphersuite... */
1262 if( opt.max_version == -1 ||
1263 opt.max_version > ciphersuite_info->max_minor_ver )
1264 {
Paul Bakker5b55b792013-07-19 13:43:43 +02001265 opt.max_version = ciphersuite_info->max_minor_ver;
Manuel Pégourié-Gonnard798f15a2014-03-26 18:12:04 +01001266 }
Paul Bakker5b55b792013-07-19 13:43:43 +02001267 if( opt.min_version < ciphersuite_info->min_minor_ver )
Manuel Pégourié-Gonnard798f15a2014-03-26 18:12:04 +01001268 {
Paul Bakker5b55b792013-07-19 13:43:43 +02001269 opt.min_version = ciphersuite_info->min_minor_ver;
Manuel Pégourié-Gonnard798f15a2014-03-26 18:12:04 +01001270 /* DTLS starts with TLS 1.1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001271 if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
1272 opt.min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
1273 opt.min_version = MBEDTLS_SSL_MINOR_VERSION_2;
Manuel Pégourié-Gonnard798f15a2014-03-26 18:12:04 +01001274 }
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001275
1276 /* Enable RC4 if needed and not explicitly disabled */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001277 if( ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001278 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001279 if( opt.arc4 == MBEDTLS_SSL_ARC4_DISABLED )
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001280 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281 mbedtls_printf("forced RC4 ciphersuite with RC4 disabled\n");
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001282 ret = 2;
1283 goto usage;
1284 }
1285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286 opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001287 }
Paul Bakkerc1516be2013-06-29 16:01:32 +02001288 }
1289
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001290 if( opt.version_suites != NULL )
1291 {
1292 const char *name[4] = { 0 };
1293
1294 /* Parse 4-element coma-separated list */
1295 for( i = 0, p = (char *) opt.version_suites;
1296 i < 4 && *p != '\0';
1297 i++ )
1298 {
1299 name[i] = p;
1300
1301 /* Terminate the current string and move on to next one */
1302 while( *p != ',' && *p != '\0' )
1303 p++;
1304 if( *p == ',' )
1305 *p++ = '\0';
1306 }
1307
1308 if( i != 4 )
1309 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310 mbedtls_printf( "too few values for version_suites\n" );
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001311 ret = 1;
1312 goto exit;
1313 }
1314
1315 memset( version_suites, 0, sizeof( version_suites ) );
1316
1317 /* Get the suites identifiers from their name */
1318 for( i = 0; i < 4; i++ )
1319 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001320 version_suites[i][0] = mbedtls_ssl_get_ciphersuite_id( name[i] );
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001321
1322 if( version_suites[i][0] == 0 )
1323 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001324 mbedtls_printf( "unknown ciphersuite: '%s'\n", name[i] );
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001325 ret = 2;
1326 goto usage;
1327 }
1328 }
1329 }
1330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001331#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001332 /*
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +02001333 * Unhexify the pre-shared key and parse the list if any given
Paul Bakkerfbb17802013-04-17 19:10:21 +02001334 */
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +02001335 if( unhexify( psk, opt.psk, &psk_len ) != 0 )
Paul Bakkerfbb17802013-04-17 19:10:21 +02001336 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337 mbedtls_printf( "pre-shared key not valid hex\n" );
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +02001338 goto exit;
1339 }
1340
1341 if( opt.psk_list != NULL )
1342 {
1343 if( ( psk_info = psk_parse( opt.psk_list ) ) == NULL )
Paul Bakkerfbb17802013-04-17 19:10:21 +02001344 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345 mbedtls_printf( "psk_list invalid" );
Paul Bakkerfbb17802013-04-17 19:10:21 +02001346 goto exit;
1347 }
Paul Bakkerfbb17802013-04-17 19:10:21 +02001348 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001349#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerfbb17802013-04-17 19:10:21 +02001350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001352 if( opt.alpn_string != NULL )
1353 {
1354 p = (char *) opt.alpn_string;
1355 i = 0;
1356
1357 /* Leave room for a final NULL in alpn_list */
1358 while( i < (int) sizeof alpn_list - 1 && *p != '\0' )
1359 {
1360 alpn_list[i++] = p;
1361
1362 /* Terminate the current string and move on to next one */
1363 while( *p != ',' && *p != '\0' )
1364 p++;
1365 if( *p == ',' )
1366 *p++ = '\0';
1367 }
1368 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369#endif /* MBEDTLS_SSL_ALPN */
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001370
Paul Bakkerfbb17802013-04-17 19:10:21 +02001371 /*
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001372 * 0. Initialize the RNG and the session data
1373 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001374 mbedtls_printf( "\n . Seeding the random number generator..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001375 fflush( stdout );
1376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377 mbedtls_entropy_init( &entropy );
Manuel Pégourié-Gonnardec160c02015-04-28 22:52:30 +02001378 if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
Paul Bakkeref3f8c72013-06-24 13:01:08 +02001379 (const unsigned char *) pers,
1380 strlen( pers ) ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001381 {
Manuel Pégourié-Gonnardec160c02015-04-28 22:52:30 +02001382 mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001383 goto exit;
1384 }
1385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001386 mbedtls_printf( " ok\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388#if defined(MBEDTLS_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001389 /*
1390 * 1.1. Load the trusted CA
1391 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 mbedtls_printf( " . Loading the CA root certificate ..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001393 fflush( stdout );
1394
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001395#if defined(MBEDTLS_FS_IO)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001396 if( strlen( opt.ca_path ) )
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001397 if( strcmp( opt.ca_path, "none" ) == 0 )
1398 ret = 0;
1399 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 ret = mbedtls_x509_crt_parse_path( &cacert, opt.ca_path );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001401 else if( strlen( opt.ca_file ) )
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001402 if( strcmp( opt.ca_file, "none" ) == 0 )
1403 ret = 0;
1404 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001405 ret = mbedtls_x509_crt_parse_file( &cacert, opt.ca_file );
Paul Bakkerddf26b42013-09-18 13:46:23 +02001406 else
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001407#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408#if defined(MBEDTLS_CERTS_C)
1409 for( i = 0; mbedtls_test_cas[i] != NULL; i++ )
Manuel Pégourié-Gonnard2f165062015-03-27 10:20:26 +01001410 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411 ret = mbedtls_x509_crt_parse( &cacert,
1412 (const unsigned char *) mbedtls_test_cas[i],
1413 mbedtls_test_cas_len[i] );
Manuel Pégourié-Gonnard2f165062015-03-27 10:20:26 +01001414 if( ret != 0 )
1415 break;
1416 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001417#else
1418 {
1419 ret = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 mbedtls_printf("MBEDTLS_CERTS_C not defined.");
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001421 }
1422#endif
1423 if( ret < 0 )
1424 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001426 goto exit;
1427 }
1428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429 mbedtls_printf( " ok (%d skipped)\n", ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001430
1431 /*
1432 * 1.2. Load own certificate and private key
1433 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001434 mbedtls_printf( " . Loading the server cert. and key..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001435 fflush( stdout );
1436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001438 if( strlen( opt.crt_file ) && strcmp( opt.crt_file, "none" ) != 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001439 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001440 key_cert_init++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441 if( ( ret = mbedtls_x509_crt_parse_file( &srvcert, opt.crt_file ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001442 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned -0x%x\n\n",
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001444 -ret );
1445 goto exit;
1446 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001447 }
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001448 if( strlen( opt.key_file ) && strcmp( opt.key_file, "none" ) != 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001449 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001450 key_cert_init++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451 if( ( ret = mbedtls_pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001452 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001454 goto exit;
1455 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001456 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001457 if( key_cert_init == 1 )
1458 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459 mbedtls_printf( " failed\n ! crt_file without key_file or vice-versa\n\n" );
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001460 goto exit;
1461 }
1462
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001463 if( strlen( opt.crt_file2 ) && strcmp( opt.crt_file2, "none" ) != 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001464 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001465 key_cert_init2++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466 if( ( ret = mbedtls_x509_crt_parse_file( &srvcert2, opt.crt_file2 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001467 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file(2) returned -0x%x\n\n",
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001469 -ret );
1470 goto exit;
1471 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001472 }
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001473 if( strlen( opt.key_file2 ) && strcmp( opt.key_file2, "none" ) != 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001474 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001475 key_cert_init2++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 if( ( ret = mbedtls_pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001477 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478 mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile(2) returned -0x%x\n\n",
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001479 -ret );
1480 goto exit;
1481 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001482 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001483 if( key_cert_init2 == 1 )
1484 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485 mbedtls_printf( " failed\n ! crt_file2 without key_file2 or vice-versa\n\n" );
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001486 goto exit;
1487 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001488#endif
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001489 if( key_cert_init == 0 &&
1490 strcmp( opt.crt_file, "none" ) != 0 &&
1491 strcmp( opt.key_file, "none" ) != 0 &&
1492 key_cert_init2 == 0 &&
1493 strcmp( opt.crt_file2, "none" ) != 0 &&
1494 strcmp( opt.key_file2, "none" ) != 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001495 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001496#if !defined(MBEDTLS_CERTS_C)
1497 mbedtls_printf( "Not certificated or key provided, and \n"
1498 "MBEDTLS_CERTS_C not defined!\n" );
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001499 goto exit;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001500#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001501#if defined(MBEDTLS_RSA_C)
1502 if( ( ret = mbedtls_x509_crt_parse( &srvcert,
1503 (const unsigned char *) mbedtls_test_srv_crt_rsa,
1504 mbedtls_test_srv_crt_rsa_len ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001505 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001507 goto exit;
1508 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001509 if( ( ret = mbedtls_pk_parse_key( &pkey,
1510 (const unsigned char *) mbedtls_test_srv_key_rsa,
1511 mbedtls_test_srv_key_rsa_len, NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001512 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001514 goto exit;
1515 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001516 key_cert_init = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517#endif /* MBEDTLS_RSA_C */
1518#if defined(MBEDTLS_ECDSA_C)
1519 if( ( ret = mbedtls_x509_crt_parse( &srvcert2,
1520 (const unsigned char *) mbedtls_test_srv_crt_ec,
1521 mbedtls_test_srv_crt_ec_len ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001522 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523 mbedtls_printf( " failed\n ! x509_crt_parse2 returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001524 goto exit;
1525 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 if( ( ret = mbedtls_pk_parse_key( &pkey2,
1527 (const unsigned char *) mbedtls_test_srv_key_ec,
1528 mbedtls_test_srv_key_ec_len, NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001529 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530 mbedtls_printf( " failed\n ! pk_parse_key2 returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001531 goto exit;
1532 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001533 key_cert_init2 = 2;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#endif /* MBEDTLS_ECDSA_C */
1535#endif /* MBEDTLS_CERTS_C */
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +02001536 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538 mbedtls_printf( " ok\n" );
1539#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001541#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001542 if( opt.dhm_file != NULL )
1543 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544 mbedtls_printf( " . Loading DHM parameters..." );
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001545 fflush( stdout );
1546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547 if( ( ret = mbedtls_dhm_parse_dhmfile( &dhm, opt.dhm_file ) ) != 0 )
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001548 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549 mbedtls_printf( " failed\n ! mbedtls_dhm_parse_dhmfile returned -0x%04X\n\n",
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001550 -ret );
1551 goto exit;
1552 }
1553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554 mbedtls_printf( " ok\n" );
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001555 }
1556#endif
1557
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +02001558#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001559 if( opt.sni != NULL )
1560 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001561 mbedtls_printf( " . Setting up SNI information..." );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001562 fflush( stdout );
1563
1564 if( ( sni_info = sni_parse( opt.sni ) ) == NULL )
1565 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566 mbedtls_printf( " failed\n" );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001567 goto exit;
1568 }
1569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570 mbedtls_printf( " ok\n" );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001571 }
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +02001572#endif /* SNI_OPTION */
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001573
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001574 /*
1575 * 2. Setup the listening TCP socket
1576 */
Manuel Pégourié-Gonnardc0d74942015-06-23 12:30:57 +02001577 mbedtls_printf( " . Bind on %s://%s:%s/ ...",
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001578 opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ? "tcp" : "udp",
Manuel Pégourié-Gonnard8a06d9c2014-03-23 18:23:41 +01001579 opt.server_addr ? opt.server_addr : "*",
1580 opt.server_port );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001581 fflush( stdout );
1582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583 if( ( ret = mbedtls_net_bind( &listen_fd, opt.server_addr, opt.server_port,
1584 opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
1585 MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001586 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001587 mbedtls_printf( " failed\n ! mbedtls_net_bind returned -0x%x\n\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001588 goto exit;
1589 }
1590
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001591 mbedtls_printf( " ok\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001592
1593 /*
1594 * 3. Setup stuff
1595 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596 mbedtls_printf( " . Setting up the SSL/TLS structure..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001597 fflush( stdout );
1598
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +02001599 if( ( ret = mbedtls_ssl_config_defaults( &conf,
1600 MBEDTLS_SSL_IS_SERVER,
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +02001601 opt.transport,
1602 MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +02001603 {
1604 mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
1605 goto exit;
1606 }
1607
Manuel Pégourié-Gonnardfa44f202015-03-27 17:52:25 +01001608 if( opt.auth_mode != DFL_AUTH_MODE )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001609 mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001611#if defined(MBEDTLS_SSL_PROTO_DTLS)
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +02001612 if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001613 mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnardd823bd02014-10-01 14:40:56 +02001615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001616#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001617 if( ( ret = mbedtls_ssl_conf_max_frag_len( &conf, opt.mfl_code ) ) != 0 )
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001618 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001619 mbedtls_printf( " failed\n ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret );
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001620 goto exit;
1621 };
Paul Bakker05decb22013-08-15 13:33:48 +02001622#endif
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +02001623
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001624#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +01001625 if( opt.trunc_hmac != DFL_TRUNC_HMAC )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001626 mbedtls_ssl_conf_truncated_hmac( &conf, opt.trunc_hmac );
Manuel Pégourié-Gonnarde117a8f2015-01-09 12:39:35 +01001627#endif
1628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001629#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001630 if( opt.extended_ms != DFL_EXTENDED_MS )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001631 mbedtls_ssl_conf_extended_master_secret( &conf, opt.extended_ms );
Manuel Pégourié-Gonnard367381f2014-10-20 18:40:56 +02001632#endif
1633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001634#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001635 if( opt.etm != DFL_ETM )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001636 mbedtls_ssl_conf_encrypt_then_mac( &conf, opt.etm );
Manuel Pégourié-Gonnard699cafa2014-10-27 13:57:03 +01001637#endif
1638
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001639#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001640 if( opt.alpn_string != NULL )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001641 if( ( ret = mbedtls_ssl_conf_alpn_protocols( &conf, alpn_list ) ) != 0 )
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001642 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001643 mbedtls_printf( " failed\n ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n", ret );
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001644 goto exit;
1645 }
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001646#endif
1647
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001648 mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
1649 mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001651#if defined(MBEDTLS_SSL_CACHE_C)
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +01001652 if( opt.cache_max != -1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001653 mbedtls_ssl_cache_set_max_entries( &cache, opt.cache_max );
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +01001654
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +01001655 if( opt.cache_timeout != -1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001656 mbedtls_ssl_cache_set_timeout( &cache, opt.cache_timeout );
Manuel Pégourié-Gonnardc55a5b72014-02-20 22:50:56 +01001657
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001658 mbedtls_ssl_conf_session_cache( &conf, &cache,
Manuel Pégourié-Gonnard5cb33082015-05-06 18:06:26 +01001659 mbedtls_ssl_cache_get,
1660 mbedtls_ssl_cache_set );
Paul Bakker0a597072012-09-25 21:55:46 +00001661#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001663#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02001664 if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED )
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001665 {
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02001666 if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx,
1667 mbedtls_ctr_drbg_random, &ctr_drbg,
Manuel Pégourié-Gonnarda0adc1b2015-05-25 10:35:16 +02001668 MBEDTLS_CIPHER_AES_256_GCM,
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02001669 opt.ticket_timeout ) ) != 0 )
1670 {
1671 mbedtls_printf( " failed\n ! mbedtls_ssl_ticket_setup returned %d\n\n", ret );
1672 goto exit;
1673 }
Manuel Pégourié-Gonnarddbe1ee12014-02-21 09:18:13 +01001674
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02001675 mbedtls_ssl_conf_session_tickets_cb( &conf,
1676 mbedtls_ssl_ticket_write,
1677 mbedtls_ssl_ticket_parse,
1678 &ticket_ctx );
1679 }
Paul Bakkera503a632013-08-14 13:48:06 +02001680#endif
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +02001681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001682#if defined(MBEDTLS_SSL_PROTO_DTLS)
1683 if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard98545f12014-07-22 22:10:43 +02001684 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001685#if defined(MBEDTLS_SSL_COOKIE_C)
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001686 if( opt.cookies > 0 )
Manuel Pégourié-Gonnardd485d192014-07-23 14:56:15 +02001687 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688 if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx,
1689 mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001690 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691 mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret );
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001692 goto exit;
1693 }
Manuel Pégourié-Gonnardd485d192014-07-23 14:56:15 +02001694
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001695 mbedtls_ssl_conf_dtls_cookies( &conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001696 &cookie_ctx );
1697 }
1698 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699#endif /* MBEDTLS_SSL_COOKIE_C */
1700#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001701 if( opt.cookies == 0 )
1702 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001703 mbedtls_ssl_conf_dtls_cookies( &conf, NULL, NULL, NULL );
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001704 }
1705 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001706#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
Manuel Pégourié-Gonnard26820e32014-07-23 19:34:59 +02001707 {
1708 ; /* Nothing to do */
1709 }
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02001710
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001711#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02001712 if( opt.anti_replay != DFL_ANTI_REPLAY )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001713 mbedtls_ssl_conf_dtls_anti_replay( &conf, opt.anti_replay );
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +02001714#endif
1715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001716#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
Manuel Pégourié-Gonnarde698f592014-10-14 19:36:36 +02001717 if( opt.badmac_limit != DFL_BADMAC_LIMIT )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001718 mbedtls_ssl_conf_dtls_badmac_limit( &conf, opt.badmac_limit );
Manuel Pégourié-Gonnard27393132014-09-24 14:41:11 +02001719#endif
Manuel Pégourié-Gonnard98545f12014-07-22 22:10:43 +02001720 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001721#endif /* MBEDTLS_SSL_PROTO_DTLS */
Manuel Pégourié-Gonnard98545f12014-07-22 22:10:43 +02001722
Paul Bakker41c83d32013-03-20 14:39:14 +01001723 if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001724 mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001725
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02001726#if defined(MBEDTLS_ARC4_C)
Manuel Pégourié-Gonnardd42b7c82015-03-20 19:44:04 +00001727 if( opt.arc4 != DFL_ARC4 )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001728 mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 );
Manuel Pégourié-Gonnard66dc5552015-05-14 12:28:21 +02001729#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001730
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001731 if( opt.version_suites != NULL )
1732 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001733 mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[0],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001734 MBEDTLS_SSL_MAJOR_VERSION_3,
1735 MBEDTLS_SSL_MINOR_VERSION_0 );
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001736 mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[1],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001737 MBEDTLS_SSL_MAJOR_VERSION_3,
1738 MBEDTLS_SSL_MINOR_VERSION_1 );
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001739 mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[2],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001740 MBEDTLS_SSL_MAJOR_VERSION_3,
1741 MBEDTLS_SSL_MINOR_VERSION_2 );
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001742 mbedtls_ssl_conf_ciphersuites_for_version( &conf, version_suites[3],
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001743 MBEDTLS_SSL_MAJOR_VERSION_3,
1744 MBEDTLS_SSL_MINOR_VERSION_3 );
Manuel Pégourié-Gonnard6dc07812014-06-11 13:50:34 +02001745 }
1746
Manuel Pégourié-Gonnard85d915b2014-11-03 20:10:36 +01001747 if( opt.allow_legacy != DFL_ALLOW_LEGACY )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001748 mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001750 mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation );
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +01001751
Manuel Pégourié-Gonnardfae355e2014-07-04 14:32:27 +02001752 if( opt.renego_delay != DFL_RENEGO_DELAY )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001753 mbedtls_ssl_conf_renegotiation_enforced( &conf, opt.renego_delay );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001754
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +01001755 if( opt.renego_period != DFL_RENEGO_PERIOD )
1756 {
1757 renego_period[7] = opt.renego_period;
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001758 mbedtls_ssl_conf_renegotiation_period( &conf, renego_period );
Manuel Pégourié-Gonnard590f4162014-11-05 14:23:03 +01001759 }
Manuel Pégourié-Gonnard615e6772014-11-03 08:23:14 +01001760#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001761
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001762#if defined(MBEDTLS_X509_CRT_PARSE_C)
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001763 if( strcmp( opt.ca_path, "none" ) != 0 &&
1764 strcmp( opt.ca_file, "none" ) != 0 )
1765 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001766 mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
Manuel Pégourié-Gonnard3e1b1782014-02-27 13:35:00 +01001767 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001768 if( key_cert_init )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001769 if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001770 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001771 mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001772 goto exit;
1773 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +02001774 if( key_cert_init2 )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001775 if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, &pkey2 ) ) != 0 )
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001776 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001777 mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
Manuel Pégourié-Gonnardc5fd3912014-07-08 14:05:52 +02001778 goto exit;
1779 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +02001780#endif
Paul Bakkered27a042013-04-18 22:46:23 +02001781
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +02001782#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001783 if( opt.sni != NULL )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001784 mbedtls_ssl_conf_sni( &conf, sni_callback, sni_info );
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01001785#endif
1786
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001787#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Manuel Pégourié-Gonnarddc019b92014-06-10 15:24:51 +02001788 if( strlen( opt.psk ) != 0 && strlen( opt.psk_identity ) != 0 )
1789 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001790 ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
Manuel Pégourié-Gonnarddc019b92014-06-10 15:24:51 +02001791 (const unsigned char *) opt.psk_identity,
1792 strlen( opt.psk_identity ) );
1793 if( ret != 0 )
1794 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001795 mbedtls_printf( " failed\n mbedtls_ssl_conf_psk returned -0x%04X\n\n", - ret );
Manuel Pégourié-Gonnarddc019b92014-06-10 15:24:51 +02001796 goto exit;
1797 }
1798 }
1799
Manuel Pégourié-Gonnard80c85532014-06-10 14:01:52 +02001800 if( opt.psk_list != NULL )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001801 mbedtls_ssl_conf_psk_cb( &conf, psk_callback, psk_info );
Paul Bakkered27a042013-04-18 22:46:23 +02001802#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001803
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001804#if defined(MBEDTLS_DHM_C)
Paul Bakker5d19f862012-09-28 07:33:00 +00001805 /*
1806 * Use different group than default DHM group
1807 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001808#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001809 if( opt.dhm_file != NULL )
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001810 ret = mbedtls_ssl_conf_dh_param_ctx( &conf, &dhm );
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001811#endif
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001812 if( ret != 0 )
1813 {
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001814 mbedtls_printf( " failed\n mbedtls_ssl_conf_dh_param returned -0x%04X\n\n", - ret );
Manuel Pégourié-Gonnard736699c2014-06-09 11:29:50 +02001815 goto exit;
1816 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001817#endif
1818
Manuel Pégourié-Gonnard8c8be1e2015-03-31 14:21:11 +02001819 if( opt.min_version != DFL_MIN_VERSION )
Manuel Pégourié-Gonnard01e5e8c2015-05-11 10:11:56 +02001820 mbedtls_ssl_conf_min_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.min_version );
Paul Bakker1d29fb52012-09-28 13:28:45 +00001821
Manuel Pégourié-Gonnard8c8be1e2015-03-31 14:21:11 +02001822 if( opt.max_version != DFL_MIN_VERSION )
Manuel Pégourié-Gonnard01e5e8c2015-05-11 10:11:56 +02001823 mbedtls_ssl_conf_max_version( &conf, MBEDTLS_SSL_MAJOR_VERSION_3, opt.max_version );
Paul Bakkerc1516be2013-06-29 16:01:32 +02001824
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02001825 if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
1826 {
1827 mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
1828 goto exit;
1829 }
1830
1831 if( opt.nbio == 2 )
1832 mbedtls_ssl_set_bio( &ssl, &client_fd, my_send, my_recv, NULL );
1833 else
1834 mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv,
Manuel Pégourié-Gonnardd4f04db2015-05-14 18:58:17 +02001835 opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
Manuel Pégourié-Gonnard06939ce2015-05-11 11:25:46 +02001836
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +02001837#if defined(MBEDTLS_TIMING_C)
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +02001838 mbedtls_ssl_set_timer_cb( &ssl, &timer, mbedtls_timing_set_delay,
1839 mbedtls_timing_get_delay );
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +02001840#endif
Manuel Pégourié-Gonnarde3c41ad2015-05-13 10:04:32 +02001841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 mbedtls_printf( " ok\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001843
1844reset:
Manuel Pégourié-Gonnardb6440a42014-09-20 12:03:00 +02001845#if !defined(_WIN32)
1846 if( received_sigterm )
1847 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001848 mbedtls_printf( " interrupted by SIGTERM\n" );
Manuel Pégourié-Gonnardb6440a42014-09-20 12:03:00 +02001849 ret = 0;
1850 goto exit;
1851 }
1852#endif
1853
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02001854 if( ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
1855 {
1856 mbedtls_printf( " ! Client initiated reconnection from same port\n" );
1857 goto handshake;
1858 }
1859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860#ifdef MBEDTLS_ERROR_C
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001861 if( ret != 0 )
1862 {
1863 char error_buf[100];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864 mbedtls_strerror( ret, error_buf, 100 );
1865 mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001866 }
1867#endif
1868
Manuel Pégourié-Gonnard3d7d00a2015-06-30 15:55:03 +02001869 mbedtls_net_free( &client_fd );
Manuel Pégourié-Gonnard8a06d9c2014-03-23 18:23:41 +01001870
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001871 mbedtls_ssl_session_reset( &ssl );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001872
1873 /*
1874 * 3. Wait until a client connects
1875 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001876 mbedtls_printf( " . Waiting for a remote connection ..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001877 fflush( stdout );
1878
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +02001879 if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
Manuel Pégourié-Gonnard0b104b02015-05-14 21:52:40 +02001880 client_ip, sizeof( client_ip ), &cliip_len ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001881 {
Paul Bakkerc1283d32014-08-18 11:05:51 +02001882#if !defined(_WIN32)
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +02001883 if( received_sigterm )
1884 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 mbedtls_printf( " interrupted by signal\n" );
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +02001886 ret = 0;
1887 goto exit;
1888 }
Paul Bakkerc1283d32014-08-18 11:05:51 +02001889#endif
Manuel Pégourié-Gonnarddb493302014-08-14 15:36:12 +02001890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001891 mbedtls_printf( " failed\n ! mbedtls_net_accept returned -0x%x\n\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001892 goto exit;
1893 }
1894
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +01001895 if( opt.nbio > 0 )
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +02001896 ret = mbedtls_net_set_nonblock( &client_fd );
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +01001897 else
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +02001898 ret = mbedtls_net_set_block( &client_fd );
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +01001899 if( ret != 0 )
1900 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 mbedtls_printf( " failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnard55753162014-02-26 13:47:08 +01001902 goto exit;
1903 }
1904
Manuel Pégourié-Gonnard6729e792015-05-11 09:50:24 +02001905 mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001906
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001907#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
1908 if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
Manuel Pégourié-Gonnard336b8242014-07-22 17:57:43 +02001909 {
Manuel Pégourié-Gonnard0b104b02015-05-14 21:52:40 +02001910 if( ( ret = mbedtls_ssl_set_client_transport_id( &ssl,
1911 client_ip, cliip_len ) ) != 0 )
Manuel Pégourié-Gonnard336b8242014-07-22 17:57:43 +02001912 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001913 mbedtls_printf( " failed\n ! "
Manuel Pégourié-Gonnard151dc772015-05-14 13:55:51 +02001914 "mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnard336b8242014-07-22 17:57:43 +02001915 goto exit;
1916 }
1917 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001918#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
Manuel Pégourié-Gonnard336b8242014-07-22 17:57:43 +02001919
Manuel Pégourié-Gonnard70905a72015-09-16 11:08:34 +02001920#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1921 if( opt.ecjpake_pw != DFL_ECJPAKE_PW )
1922 {
1923 if( ( ret = mbedtls_ssl_set_hs_ecjpake_password( &ssl,
1924 (const unsigned char *) opt.ecjpake_pw,
1925 strlen( opt.ecjpake_pw ) ) ) != 0 )
1926 {
1927 mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
1928 goto exit;
1929 }
1930 }
1931#endif
1932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001933 mbedtls_printf( " ok\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001934
1935 /*
1936 * 4. Handshake
1937 */
Manuel Pégourié-Gonnard3f09b6d2015-09-08 11:58:14 +02001938handshake:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001939 mbedtls_printf( " . Performing the SSL/TLS handshake..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001940 fflush( stdout );
1941
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001942 do ret = mbedtls_ssl_handshake( &ssl );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01001943 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
1944 ret == MBEDTLS_ERR_SSL_WANT_WRITE );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001946 if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
Manuel Pégourié-Gonnardcaecdae2014-10-13 19:04:37 +02001947 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001948 mbedtls_printf( " hello verification requested\n" );
Manuel Pégourié-Gonnardcaecdae2014-10-13 19:04:37 +02001949 ret = 0;
1950 goto reset;
1951 }
1952 else if( ret != 0 )
1953 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001954 mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
Manuel Pégourié-Gonnard6ea831d2015-06-22 16:50:52 +02001955
1956#if defined(MBEDTLS_X509_CRT_PARSE_C)
1957 if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
1958 {
1959 char vrfy_buf[512];
Manuel Pégourié-Gonnardea356662015-08-27 12:02:40 +02001960 flags = mbedtls_ssl_get_verify_result( &ssl );
Manuel Pégourié-Gonnard6ea831d2015-06-22 16:50:52 +02001961
1962 mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
1963
1964 mbedtls_printf( "%s\n", vrfy_buf );
1965 }
1966#endif
1967
Manuel Pégourié-Gonnardcaecdae2014-10-13 19:04:37 +02001968 goto reset;
1969 }
1970 else /* ret == 0 */
1971 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001972 mbedtls_printf( " ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
1973 mbedtls_ssl_get_version( &ssl ), mbedtls_ssl_get_ciphersuite( &ssl ) );
Manuel Pégourié-Gonnardcaecdae2014-10-13 19:04:37 +02001974 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001976 if( ( ret = mbedtls_ssl_get_record_expansion( &ssl ) ) >= 0 )
1977 mbedtls_printf( " [ Record expansion is %d ]\n", ret );
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02001978 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001979 mbedtls_printf( " [ Record expansion is unknown (compression) ]\n" );
Manuel Pégourié-Gonnard9b35f182014-10-14 17:47:31 +02001980
Manuel Pégourié-Gonnarda2cda6b2015-08-31 18:30:52 +02001981#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1982 mbedtls_printf( " [ Maximum fragment length is %u ]\n",
1983 (unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
1984#endif
1985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001986#if defined(MBEDTLS_SSL_ALPN)
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001987 if( opt.alpn_string != NULL )
1988 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001989 const char *alp = mbedtls_ssl_get_alpn_protocol( &ssl );
1990 mbedtls_printf( " [ Application Layer Protocol is %s ]\n",
Manuel Pégourié-Gonnard1bd22812014-04-05 14:34:07 +02001991 alp ? alp : "(none)" );
1992 }
1993#endif
1994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995#if defined(MBEDTLS_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001996 /*
1997 * 5. Verify the server certificate
1998 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999 mbedtls_printf( " . Verifying peer X.509 certificate..." );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002000
Manuel Pégourié-Gonnarde6ef16f2015-05-11 19:54:43 +02002001 if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002002 {
Manuel Pégourié-Gonnard89addc42015-04-20 10:56:18 +01002003 char vrfy_buf[512];
2004
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002005 mbedtls_printf( " failed\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002006
Manuel Pégourié-Gonnarde6ef16f2015-05-11 19:54:43 +02002007 mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002008
Manuel Pégourié-Gonnard89addc42015-04-20 10:56:18 +01002009 mbedtls_printf( "%s\n", vrfy_buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002010 }
2011 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 mbedtls_printf( " ok\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002013
Manuel Pégourié-Gonnard1c5b9fc2015-06-27 14:38:51 +02002014 if( mbedtls_ssl_get_peer_cert( &ssl ) != NULL )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002015 {
Manuel Pégourié-Gonnard1c5b9fc2015-06-27 14:38:51 +02002016 char crt_buf[512];
2017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002018 mbedtls_printf( " . Peer certificate information ...\n" );
Manuel Pégourié-Gonnard1c5b9fc2015-06-27 14:38:51 +02002019 mbedtls_x509_crt_info( crt_buf, sizeof( crt_buf ), " ",
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002020 mbedtls_ssl_get_peer_cert( &ssl ) );
Manuel Pégourié-Gonnard67557172015-07-02 11:15:48 +02002021 mbedtls_printf( "%s\n", crt_buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002022 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#endif /* MBEDTLS_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002024
Manuel Pégourié-Gonnard6a2bc232014-10-09 15:33:13 +02002025 if( opt.exchanges == 0 )
2026 goto close_notify;
2027
Manuel Pégourié-Gonnard6a0017b2015-01-22 10:33:29 +00002028 exchanges_left = opt.exchanges;
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002029data_exchange:
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002030 /*
2031 * 6. Read the HTTP Request
2032 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002033 mbedtls_printf( " < Read from client:" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002034 fflush( stdout );
2035
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002036 /*
2037 * TLS and DTLS need different reading styles (stream vs datagram)
2038 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039 if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002040 {
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002041 do
2042 {
2043 int terminated = 0;
2044 len = sizeof( buf ) - 1;
2045 memset( buf, 0, sizeof( buf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002046 ret = mbedtls_ssl_read( &ssl, buf, len );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002047
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002048 if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
2049 ret == MBEDTLS_ERR_SSL_WANT_WRITE )
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002050 continue;
2051
2052 if( ret <= 0 )
2053 {
2054 switch( ret )
2055 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2057 mbedtls_printf( " connection was closed gracefully\n" );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002058 goto close_notify;
2059
2060 case 0:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002061 case MBEDTLS_ERR_NET_CONN_RESET:
2062 mbedtls_printf( " connection was reset by peer\n" );
2063 ret = MBEDTLS_ERR_NET_CONN_RESET;
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002064 goto reset;
2065
2066 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067 mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002068 goto reset;
2069 }
2070 }
2071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002072 if( mbedtls_ssl_get_bytes_avail( &ssl ) == 0 )
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002073 {
2074 len = ret;
2075 buf[len] = '\0';
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076 mbedtls_printf( " %d bytes read\n\n%s\n", len, (char *) buf );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002077
2078 /* End of message should be detected according to the syntax of the
2079 * application protocol (eg HTTP), just use a dummy test here. */
2080 if( buf[len - 1] == '\n' )
2081 terminated = 1;
2082 }
2083 else
2084 {
2085 int extra_len, ori_len;
2086 unsigned char *larger_buf;
2087
2088 ori_len = ret;
Manuel Pégourié-Gonnard9de64f52015-07-01 15:51:43 +02002089 extra_len = (int) mbedtls_ssl_get_bytes_avail( &ssl );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002090
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +02002091 larger_buf = mbedtls_calloc( 1, ori_len + extra_len + 1 );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002092 if( larger_buf == NULL )
2093 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002094 mbedtls_printf( " ! memory allocation failed\n" );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002095 ret = 1;
2096 goto reset;
2097 }
2098
2099 memset( larger_buf, 0, ori_len + extra_len );
2100 memcpy( larger_buf, buf, ori_len );
2101
2102 /* This read should never fail and get the whole cached data */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103 ret = mbedtls_ssl_read( &ssl, larger_buf + ori_len, extra_len );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002104 if( ret != extra_len ||
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105 mbedtls_ssl_get_bytes_avail( &ssl ) != 0 )
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002106 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107 mbedtls_printf( " ! mbedtls_ssl_read failed on cached data\n" );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002108 ret = 1;
2109 goto reset;
2110 }
2111
2112 larger_buf[ori_len + extra_len] = '\0';
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113 mbedtls_printf( " %u bytes read (%u + %u)\n\n%s\n",
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002114 ori_len + extra_len, ori_len, extra_len,
2115 (char *) larger_buf );
2116
2117 /* End of message should be detected according to the syntax of the
2118 * application protocol (eg HTTP), just use a dummy test here. */
2119 if( larger_buf[ori_len + extra_len - 1] == '\n' )
2120 terminated = 1;
2121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002122 mbedtls_free( larger_buf );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002123 }
2124
2125 if( terminated )
2126 {
2127 ret = 0;
2128 break;
2129 }
2130 }
2131 while( 1 );
2132 }
2133 else /* Not stream, so datagram */
2134 {
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002135 len = sizeof( buf ) - 1;
2136 memset( buf, 0, sizeof( buf ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002138 do ret = mbedtls_ssl_read( &ssl, buf, len );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002139 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
2140 ret == MBEDTLS_ERR_SSL_WANT_WRITE );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002141
2142 if( ret <= 0 )
2143 {
2144 switch( ret )
2145 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002146 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2147 mbedtls_printf( " connection was closed gracefully\n" );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002148 ret = 0;
Manuel Pégourié-Gonnarde08660e2014-08-16 11:28:40 +02002149 goto close_notify;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002150
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002151 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002152 mbedtls_printf( " mbedtls_ssl_read returned -0x%x\n", -ret );
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002153 goto reset;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002154 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002155 }
2156
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002157 len = ret;
2158 buf[len] = '\0';
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002159 mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
Manuel Pégourié-Gonnardcce220d2014-10-06 18:11:43 +02002160 ret = 0;
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002161 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002162
2163 /*
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002164 * 7a. Request renegotiation while client is waiting for input from us.
Manuel Pégourié-Gonnarda6ace042014-10-15 12:44:41 +02002165 * (only on the first exchange, to be able to test retransmission)
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002166 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002167#if defined(MBEDTLS_SSL_RENEGOTIATION)
Manuel Pégourié-Gonnard3a173f42015-01-22 13:30:33 +00002168 if( opt.renegotiate && exchanges_left == opt.exchanges )
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002169 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002170 mbedtls_printf( " . Requestion renegotiation..." );
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002171 fflush( stdout );
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002173 while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002174 {
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002175 if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
2176 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002178 mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002179 goto reset;
2180 }
2181 }
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002183 mbedtls_printf( " ok\n" );
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002184 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185#endif /* MBEDTLS_SSL_RENEGOTIATION */
Manuel Pégourié-Gonnard296e3b12014-08-19 12:59:03 +02002186
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002187 /*
2188 * 7. Write the 200 Response
2189 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002190 mbedtls_printf( " > Write to client:" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002191 fflush( stdout );
2192
2193 len = sprintf( (char *) buf, HTTP_RESPONSE,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194 mbedtls_ssl_get_ciphersuite( &ssl ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002196 if( opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002197 {
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002198 for( written = 0, frags = 0; written < len; written += ret, frags++ )
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002199 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002200 while( ( ret = mbedtls_ssl_write( &ssl, buf + written, len - written ) )
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002201 <= 0 )
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02002202 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002203 if( ret == MBEDTLS_ERR_NET_CONN_RESET )
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002204 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002205 mbedtls_printf( " failed\n ! peer closed the connection\n\n" );
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002206 goto reset;
2207 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002208
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002209 if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
2210 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002211 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002212 mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002213 goto reset;
2214 }
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02002215 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002216 }
2217 }
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002218 else /* Not stream, so datagram */
2219 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220 do ret = mbedtls_ssl_write( &ssl, buf, len );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002221 while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
2222 ret == MBEDTLS_ERR_SSL_WANT_WRITE );
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002223
2224 if( ret < 0 )
2225 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002226 mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
Manuel Pégourié-Gonnard2d87e412014-10-13 18:38:36 +02002227 goto reset;
2228 }
2229
2230 frags = 1;
2231 written = ret;
2232 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002233
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +02002234 buf[written] = '\0';
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235 mbedtls_printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );
Manuel Pégourié-Gonnarda92ed482015-01-14 10:46:08 +01002236 ret = 0;
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01002237
Manuel Pégourié-Gonnarde08660e2014-08-16 11:28:40 +02002238 /*
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002239 * 7b. Continue doing data exchanges?
2240 */
Manuel Pégourié-Gonnard6a0017b2015-01-22 10:33:29 +00002241 if( --exchanges_left > 0 )
Manuel Pégourié-Gonnarda8c0a0d2014-08-15 12:07:38 +02002242 goto data_exchange;
2243
2244 /*
2245 * 8. Done, cleanly close the connection
Manuel Pégourié-Gonnarde08660e2014-08-16 11:28:40 +02002246 */
2247close_notify:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002248 mbedtls_printf( " . Closing the connection..." );
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +01002249
Manuel Pégourié-Gonnard994f8b52014-10-09 19:56:44 +02002250 /* No error checking, the connection might be closed already */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251 do ret = mbedtls_ssl_close_notify( &ssl );
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +01002252 while( ret == MBEDTLS_ERR_SSL_WANT_WRITE );
Manuel Pégourié-Gonnard994f8b52014-10-09 19:56:44 +02002253 ret = 0;
Manuel Pégourié-Gonnarde08660e2014-08-16 11:28:40 +02002254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002255 mbedtls_printf( " done\n" );
Rich Evansf90016a2015-01-19 14:26:37 +00002256
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002257 goto reset;
2258
Manuel Pégourié-Gonnarde08660e2014-08-16 11:28:40 +02002259 /*
2260 * Cleanup and exit
2261 */
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002262exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002263#ifdef MBEDTLS_ERROR_C
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002264 if( ret != 0 )
2265 {
2266 char error_buf[100];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002267 mbedtls_strerror( ret, error_buf, 100 );
2268 mbedtls_printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002269 }
2270#endif
2271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272 mbedtls_printf( " . Cleaning up..." );
Manuel Pégourié-Gonnardf29e5de2014-11-21 11:54:41 +01002273 fflush( stdout );
2274
Manuel Pégourié-Gonnard3d7d00a2015-06-30 15:55:03 +02002275 mbedtls_net_free( &client_fd );
2276 mbedtls_net_free( &listen_fd );
Paul Bakker0c226102014-04-17 16:02:36 +02002277
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002278#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
2279 mbedtls_dhm_free( &dhm );
Paul Bakkera317a982014-06-18 16:44:11 +02002280#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002281#if defined(MBEDTLS_X509_CRT_PARSE_C)
2282 mbedtls_x509_crt_free( &cacert );
2283 mbedtls_x509_crt_free( &srvcert );
2284 mbedtls_pk_free( &pkey );
2285 mbedtls_x509_crt_free( &srvcert2 );
2286 mbedtls_pk_free( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +02002287#endif
Manuel Pégourié-Gonnard6c7af4c2015-04-03 16:41:52 +02002288#if defined(SNI_OPTION)
Manuel Pégourié-Gonnard5d917ff2014-02-21 16:52:06 +01002289 sni_free( sni_info );
2290#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002291#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
Manuel Pégourié-Gonnard4505ed32014-06-19 20:56:52 +02002292 psk_free( psk_info );
2293#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002294#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
2295 mbedtls_dhm_free( &dhm );
Manuel Pégourié-Gonnard4505ed32014-06-19 20:56:52 +02002296#endif
Paul Bakkered27a042013-04-18 22:46:23 +02002297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002298 mbedtls_ssl_free( &ssl );
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +02002299 mbedtls_ssl_config_free( &conf );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002300 mbedtls_ctr_drbg_free( &ctr_drbg );
2301 mbedtls_entropy_free( &entropy );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303#if defined(MBEDTLS_SSL_CACHE_C)
2304 mbedtls_ssl_cache_free( &cache );
Paul Bakker0a597072012-09-25 21:55:46 +00002305#endif
Manuel Pégourié-Gonnardd59675d2015-05-19 15:28:00 +02002306#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2307 mbedtls_ssl_ticket_free( &ticket_ctx );
2308#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002309#if defined(MBEDTLS_SSL_COOKIE_C)
2310 mbedtls_ssl_cookie_free( &cookie_ctx );
Manuel Pégourié-Gonnardd485d192014-07-23 14:56:15 +02002311#endif
Paul Bakker0a597072012-09-25 21:55:46 +00002312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002313#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
2314#if defined(MBEDTLS_MEMORY_DEBUG)
2315 mbedtls_memory_buffer_alloc_status();
Paul Bakker82024bf2013-07-04 11:52:32 +02002316#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317 mbedtls_memory_buffer_alloc_free();
Paul Bakker1337aff2013-09-29 14:45:34 +02002318#endif
Paul Bakker82024bf2013-07-04 11:52:32 +02002319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320 mbedtls_printf( " done.\n" );
Manuel Pégourié-Gonnardf29e5de2014-11-21 11:54:41 +01002321
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002322#if defined(_WIN32)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002323 mbedtls_printf( " + Press Enter to exit this program.\n" );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002324 fflush( stdout ); getchar();
2325#endif
2326
Paul Bakkerdbd79ca2013-07-24 16:28:35 +02002327 // Shell can not handle large exit numbers -> 1 for errors
2328 if( ret < 0 )
2329 ret = 1;
2330
Paul Bakkerb60b95f2012-09-25 09:05:17 +00002331 return( ret );
2332}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
2334 MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C && MBEDTLS_RSA_C &&
Manuel Pégourié-Gonnardd2377e72015-05-13 13:58:56 +02002335 MBEDTLS_CTR_DRBG_C */