blob: 54ba769b43379e54b2944f305b58bc4f601ddbf0 [file] [log] [blame]
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001/*
2 * SSL client with options
3 *
Paul Bakker3c5ef712013-06-25 16:37:45 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerb60b95f2012-09-25 09:05:17 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
Manuel Pégourié-Gonnardabd6e022013-09-20 13:30:43 +020026#include "polarssl/config.h"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000027
28#if defined(_WIN32)
29#include <windows.h>
30#endif
31
32#include <string.h>
33#include <stdlib.h>
34#include <stdio.h>
35
Paul Bakkerb60b95f2012-09-25 09:05:17 +000036#include "polarssl/net.h"
37#include "polarssl/ssl.h"
38#include "polarssl/entropy.h"
39#include "polarssl/ctr_drbg.h"
40#include "polarssl/certs.h"
41#include "polarssl/x509.h"
42#include "polarssl/error.h"
43
Paul Bakker0a597072012-09-25 21:55:46 +000044#if defined(POLARSSL_SSL_CACHE_C)
45#include "polarssl/ssl_cache.h"
46#endif
47
Paul Bakker82024bf2013-07-04 11:52:32 +020048#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
49#include "polarssl/memory.h"
50#endif
51
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +010052#define DFL_SERVER_ADDR NULL
Paul Bakkerb60b95f2012-09-25 09:05:17 +000053#define DFL_SERVER_PORT 4433
Paul Bakkerb60b95f2012-09-25 09:05:17 +000054#define DFL_DEBUG_LEVEL 0
55#define DFL_CA_FILE ""
56#define DFL_CA_PATH ""
57#define DFL_CRT_FILE ""
58#define DFL_KEY_FILE ""
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +020059#define DFL_CRT_FILE2 ""
60#define DFL_KEY_FILE2 ""
Paul Bakkerfbb17802013-04-17 19:10:21 +020061#define DFL_PSK ""
62#define DFL_PSK_IDENTITY "Client_identity"
Paul Bakkerb60b95f2012-09-25 09:05:17 +000063#define DFL_FORCE_CIPHER 0
64#define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED
65#define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +010066#define DFL_RENEGOTIATE 0
Paul Bakker1d29fb52012-09-28 13:28:45 +000067#define DFL_MIN_VERSION -1
Paul Bakkerc1516be2013-06-29 16:01:32 +020068#define DFL_MAX_VERSION -1
Paul Bakker91ebfb52012-11-23 14:04:08 +010069#define DFL_AUTH_MODE SSL_VERIFY_OPTIONAL
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +020070#define DFL_MFL_CODE SSL_MAX_FRAG_LEN_NONE
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +020071#define DFL_TICKETS SSL_SESSION_TICKETS_ENABLED
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +010072#define DFL_CACHE_MAX -1
Paul Bakkerb60b95f2012-09-25 09:05:17 +000073
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +020074#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
75 "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
76 "03-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
77 "04-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
78 "05-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
79 "06-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
80 "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 +020081
Paul Bakker8e714d72013-07-18 11:05:13 +020082/* Uncomment LONG_RESPONSE at the end of HTTP_RESPONSE to test sending longer
83 * packets (for fragmentation purposes) */
Paul Bakkerb60b95f2012-09-25 09:05:17 +000084#define HTTP_RESPONSE \
85 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
86 "<h2>PolarSSL Test Server</h2>\r\n" \
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +020087 "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
Paul Bakkerb60b95f2012-09-25 09:05:17 +000088
89/*
Paul Bakkerb60b95f2012-09-25 09:05:17 +000090 * global options
91 */
92struct options
93{
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +010094 const char *server_addr; /* address on which the ssl service runs */
Paul Bakkerb60b95f2012-09-25 09:05:17 +000095 int server_port; /* port on which the ssl service runs */
96 int debug_level; /* level of debugging */
Paul Bakkeref3f8c72013-06-24 13:01:08 +020097 const char *ca_file; /* the file with the CA certificate(s) */
98 const char *ca_path; /* the path with the CA certificate(s) reside */
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +020099 const char *crt_file; /* the file with the server certificate */
100 const char *key_file; /* the file with the server key */
101 const char *crt_file2; /* the file with the 2nd server certificate */
102 const char *key_file2; /* the file with the 2nd server key */
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200103 const char *psk; /* the pre-shared key */
104 const char *psk_identity; /* the pre-shared key identity */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000105 int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
106 int renegotiation; /* enable / disable renegotiation */
107 int allow_legacy; /* allow legacy renegotiation */
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100108 int renegotiate; /* attempt renegotiation? */
Paul Bakker1d29fb52012-09-28 13:28:45 +0000109 int min_version; /* minimum protocol version accepted */
Paul Bakkerc1516be2013-06-29 16:01:32 +0200110 int max_version; /* maximum protocol version accepted */
Paul Bakker91ebfb52012-11-23 14:04:08 +0100111 int auth_mode; /* verify mode for connection */
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200112 unsigned char mfl_code; /* code for maximum fragment length */
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200113 int tickets; /* enable / disable session tickets */
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100114 int cache_max; /* max number of session cache entries */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000115} opt;
116
Paul Bakker3c5ef712013-06-25 16:37:45 +0200117static void my_debug( void *ctx, int level, const char *str )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000118{
119 if( level < opt.debug_level )
120 {
121 fprintf( (FILE *) ctx, "%s", str );
122 fflush( (FILE *) ctx );
123 }
124}
125
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200126
127#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000128#if defined(POLARSSL_FS_IO)
129#define USAGE_IO \
Paul Bakker1f9d02d2012-11-20 10:30:55 +0100130 " ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \
131 " default: \"\" (pre-loaded)\n" \
132 " ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \
133 " default: \"\" (pre-loaded) (overrides ca_file)\n" \
134 " 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 +0200135 " default: see note after key_file2\n" \
136 " key_file=%%s default: see note after key_file2\n" \
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200137 " 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 +0200138 " default: see note after key_file2\n" \
139 " key_file2=%%s default: see note below\n" \
140 " note: if neither crt_file/key_file nor crt_file2/key_file2 are used,\n" \
141 " preloaded certificate(s) and key(s) are used if available\n"
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000142#else
143#define USAGE_IO \
Paul Bakkered27a042013-04-18 22:46:23 +0200144 "\n" \
145 " No file operations available (POLARSSL_FS_IO not defined)\n" \
146 "\n"
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000147#endif /* POLARSSL_FS_IO */
Paul Bakkered27a042013-04-18 22:46:23 +0200148#else
149#define USAGE_IO ""
Paul Bakker36713e82013-09-17 13:25:29 +0200150#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkered27a042013-04-18 22:46:23 +0200151
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200152#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkered27a042013-04-18 22:46:23 +0200153#define USAGE_PSK \
154 " psk=%%s default: \"\" (in hex, without 0x)\n" \
155 " psk_identity=%%s default: \"Client_identity\"\n"
156#else
157#define USAGE_PSK ""
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200158#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000159
Paul Bakkera503a632013-08-14 13:48:06 +0200160#if defined(POLARSSL_SSL_SESSION_TICKETS)
161#define USAGE_TICKETS \
162 " tickets=%%d default: 1 (enabled)\n"
163#else
164#define USAGE_TICKETS ""
165#endif /* POLARSSL_SSL_SESSION_TICKETS */
166
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100167#if defined(POLARSSL_SSL_CACHE_C)
168#define USAGE_CACHE \
169 " cache_max=%%d default: cache default (50)\n"
170#else
171#define USAGE_CACHE ""
172#endif /* POLARSSL_SSL_CACHE_C */
173
Paul Bakker05decb22013-08-15 13:33:48 +0200174#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
175#define USAGE_MAX_FRAG_LEN \
176 " max_frag_len=%%d default: 16384 (tls default)\n" \
177 " options: 512, 1024, 2048, 4096\n"
178#else
179#define USAGE_MAX_FRAG_LEN ""
180#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */
181
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000182#define USAGE \
183 "\n usage: ssl_server2 param=<>...\n" \
184 "\n acceptable parameters:\n" \
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100185 " server_addr=%%d default: (all interfaces)\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000186 " server_port=%%d default: 4433\n" \
187 " debug_level=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100188 "\n" \
189 " auth_mode=%%s default: \"optional\"\n" \
190 " options: none, optional, required\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000191 USAGE_IO \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100192 "\n" \
193 USAGE_PSK \
194 "\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000195 " renegotiation=%%d default: 1 (enabled)\n" \
196 " allow_legacy=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100197 " renegotiate=%%d default: 0 (disabled)\n" \
Manuel Pégourié-Gonnard2fc243d2014-02-19 18:22:59 +0100198 USAGE_TICKETS \
199 USAGE_MAX_FRAG_LEN \
200 "\n" \
Paul Bakker1d29fb52012-09-28 13:28:45 +0000201 " min_version=%%s default: \"ssl3\"\n" \
Paul Bakkerc1516be2013-06-29 16:01:32 +0200202 " max_version=%%s default: \"tls1_2\"\n" \
203 " force_version=%%s default: \"\" (none)\n" \
Paul Bakker1d29fb52012-09-28 13:28:45 +0000204 " options: ssl3, tls1, tls1_1, tls1_2\n" \
Paul Bakkerfbb17802013-04-17 19:10:21 +0200205 "\n" \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000206 " force_ciphersuite=<name> default: all enabled\n"\
207 " acceptable ciphersuite names:\n"
208
Paul Bakkered27a042013-04-18 22:46:23 +0200209#if !defined(POLARSSL_ENTROPY_C) || \
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000210 !defined(POLARSSL_SSL_TLS_C) || !defined(POLARSSL_SSL_SRV_C) || \
Paul Bakkered27a042013-04-18 22:46:23 +0200211 !defined(POLARSSL_NET_C) || !defined(POLARSSL_CTR_DRBG_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000212int main( int argc, char *argv[] )
213{
214 ((void) argc);
215 ((void) argv);
216
Paul Bakkered27a042013-04-18 22:46:23 +0200217 printf("POLARSSL_ENTROPY_C and/or "
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000218 "POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or "
Paul Bakkered27a042013-04-18 22:46:23 +0200219 "POLARSSL_NET_C and/or POLARSSL_CTR_DRBG_C not defined.\n");
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000220 return( 0 );
221}
222#else
223int main( int argc, char *argv[] )
224{
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200225 int ret = 0, len, written, frags;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000226 int listen_fd;
227 int client_fd = -1;
228 unsigned char buf[1024];
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200229#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkerfbb17802013-04-17 19:10:21 +0200230 unsigned char psk[256];
231 size_t psk_len = 0;
Paul Bakkered27a042013-04-18 22:46:23 +0200232#endif
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200233 const char *pers = "ssl_server2";
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000234
235 entropy_context entropy;
236 ctr_drbg_context ctr_drbg;
237 ssl_context ssl;
Paul Bakker36713e82013-09-17 13:25:29 +0200238#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerc559c7a2013-09-18 14:13:26 +0200239 x509_crt cacert;
240 x509_crt srvcert;
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200241 pk_context pkey;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200242 x509_crt srvcert2;
243 pk_context pkey2;
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200244 int key_cert_init = 0, key_cert_init2 = 0;
Paul Bakkered27a042013-04-18 22:46:23 +0200245#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000246#if defined(POLARSSL_SSL_CACHE_C)
247 ssl_cache_context cache;
248#endif
Paul Bakker82024bf2013-07-04 11:52:32 +0200249#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
250 unsigned char alloc_buf[100000];
251#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000252
253 int i;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000254 char *p, *q;
255 const int *list;
256
Paul Bakker82024bf2013-07-04 11:52:32 +0200257#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
258 memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
259#endif
260
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000261 /*
Manuel Pégourié-Gonnard3bd2aae2013-09-20 13:10:13 +0200262 * Make sure memory references are valid in case we exit early.
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000263 */
264 listen_fd = 0;
Manuel Pégourié-Gonnard3bd2aae2013-09-20 13:10:13 +0200265 memset( &ssl, 0, sizeof( ssl_context ) );
Paul Bakker36713e82013-09-17 13:25:29 +0200266#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakker369d2eb2013-09-18 11:58:25 +0200267 x509_crt_init( &cacert );
268 x509_crt_init( &srvcert );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +0200269 pk_init( &pkey );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200270 x509_crt_init( &srvcert2 );
271 pk_init( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +0200272#endif
Paul Bakker0a597072012-09-25 21:55:46 +0000273#if defined(POLARSSL_SSL_CACHE_C)
274 ssl_cache_init( &cache );
275#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000276
277 if( argc == 0 )
278 {
279 usage:
280 if( ret == 0 )
281 ret = 1;
282
283 printf( USAGE );
284
285 list = ssl_list_ciphersuites();
286 while( *list )
287 {
Paul Bakkerbcbe2d82013-04-19 09:10:20 +0200288 printf(" %-42s", ssl_get_ciphersuite_name( *list ) );
Paul Bakkered27a042013-04-18 22:46:23 +0200289 list++;
290 if( !*list )
291 break;
292 printf(" %s\n", ssl_get_ciphersuite_name( *list ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000293 list++;
294 }
295 printf("\n");
296 goto exit;
297 }
298
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100299 opt.server_addr = DFL_SERVER_ADDR;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000300 opt.server_port = DFL_SERVER_PORT;
301 opt.debug_level = DFL_DEBUG_LEVEL;
302 opt.ca_file = DFL_CA_FILE;
303 opt.ca_path = DFL_CA_PATH;
304 opt.crt_file = DFL_CRT_FILE;
305 opt.key_file = DFL_KEY_FILE;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200306 opt.crt_file2 = DFL_CRT_FILE2;
307 opt.key_file2 = DFL_KEY_FILE2;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200308 opt.psk = DFL_PSK;
309 opt.psk_identity = DFL_PSK_IDENTITY;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000310 opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
311 opt.renegotiation = DFL_RENEGOTIATION;
312 opt.allow_legacy = DFL_ALLOW_LEGACY;
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100313 opt.renegotiate = DFL_RENEGOTIATE;
Paul Bakker1d29fb52012-09-28 13:28:45 +0000314 opt.min_version = DFL_MIN_VERSION;
Paul Bakkerc1516be2013-06-29 16:01:32 +0200315 opt.max_version = DFL_MAX_VERSION;
Paul Bakker91ebfb52012-11-23 14:04:08 +0100316 opt.auth_mode = DFL_AUTH_MODE;
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200317 opt.mfl_code = DFL_MFL_CODE;
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200318 opt.tickets = DFL_TICKETS;
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100319 opt.cache_max = DFL_CACHE_MAX;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000320
321 for( i = 1; i < argc; i++ )
322 {
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000323 p = argv[i];
324 if( ( q = strchr( p, '=' ) ) == NULL )
325 goto usage;
326 *q++ = '\0';
327
328 if( strcmp( p, "server_port" ) == 0 )
329 {
330 opt.server_port = atoi( q );
331 if( opt.server_port < 1 || opt.server_port > 65535 )
332 goto usage;
333 }
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100334 else if( strcmp( p, "server_addr" ) == 0 )
335 opt.server_addr = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000336 else if( strcmp( p, "debug_level" ) == 0 )
337 {
338 opt.debug_level = atoi( q );
339 if( opt.debug_level < 0 || opt.debug_level > 65535 )
340 goto usage;
341 }
342 else if( strcmp( p, "ca_file" ) == 0 )
343 opt.ca_file = q;
344 else if( strcmp( p, "ca_path" ) == 0 )
345 opt.ca_path = q;
346 else if( strcmp( p, "crt_file" ) == 0 )
347 opt.crt_file = q;
348 else if( strcmp( p, "key_file" ) == 0 )
349 opt.key_file = q;
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +0200350 else if( strcmp( p, "crt_file2" ) == 0 )
351 opt.crt_file2 = q;
352 else if( strcmp( p, "key_file2" ) == 0 )
353 opt.key_file2 = q;
Paul Bakkerfbb17802013-04-17 19:10:21 +0200354 else if( strcmp( p, "psk" ) == 0 )
355 opt.psk = q;
356 else if( strcmp( p, "psk_identity" ) == 0 )
357 opt.psk_identity = q;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000358 else if( strcmp( p, "force_ciphersuite" ) == 0 )
359 {
360 opt.force_ciphersuite[0] = -1;
361
362 opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q );
363
364 if( opt.force_ciphersuite[0] <= 0 )
365 {
366 ret = 2;
367 goto usage;
368 }
369 opt.force_ciphersuite[1] = 0;
370 }
371 else if( strcmp( p, "renegotiation" ) == 0 )
372 {
373 opt.renegotiation = (atoi( q )) ? SSL_RENEGOTIATION_ENABLED :
374 SSL_RENEGOTIATION_DISABLED;
375 }
376 else if( strcmp( p, "allow_legacy" ) == 0 )
377 {
378 opt.allow_legacy = atoi( q );
379 if( opt.allow_legacy < 0 || opt.allow_legacy > 1 )
380 goto usage;
381 }
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100382 else if( strcmp( p, "renegotiate" ) == 0 )
383 {
384 opt.renegotiate = atoi( q );
385 if( opt.renegotiate < 0 || opt.renegotiate > 1 )
386 goto usage;
387 }
Paul Bakker1d29fb52012-09-28 13:28:45 +0000388 else if( strcmp( p, "min_version" ) == 0 )
389 {
390 if( strcmp( q, "ssl3" ) == 0 )
391 opt.min_version = SSL_MINOR_VERSION_0;
392 else if( strcmp( q, "tls1" ) == 0 )
393 opt.min_version = SSL_MINOR_VERSION_1;
394 else if( strcmp( q, "tls1_1" ) == 0 )
395 opt.min_version = SSL_MINOR_VERSION_2;
396 else if( strcmp( q, "tls1_2" ) == 0 )
397 opt.min_version = SSL_MINOR_VERSION_3;
398 else
399 goto usage;
400 }
Paul Bakkerc1516be2013-06-29 16:01:32 +0200401 else if( strcmp( p, "max_version" ) == 0 )
402 {
403 if( strcmp( q, "ssl3" ) == 0 )
404 opt.max_version = SSL_MINOR_VERSION_0;
405 else if( strcmp( q, "tls1" ) == 0 )
406 opt.max_version = SSL_MINOR_VERSION_1;
407 else if( strcmp( q, "tls1_1" ) == 0 )
408 opt.max_version = SSL_MINOR_VERSION_2;
409 else if( strcmp( q, "tls1_2" ) == 0 )
410 opt.max_version = SSL_MINOR_VERSION_3;
411 else
412 goto usage;
413 }
414 else if( strcmp( p, "force_version" ) == 0 )
415 {
416 if( strcmp( q, "ssl3" ) == 0 )
417 {
418 opt.min_version = SSL_MINOR_VERSION_0;
419 opt.max_version = SSL_MINOR_VERSION_0;
420 }
421 else if( strcmp( q, "tls1" ) == 0 )
422 {
423 opt.min_version = SSL_MINOR_VERSION_1;
424 opt.max_version = SSL_MINOR_VERSION_1;
425 }
426 else if( strcmp( q, "tls1_1" ) == 0 )
427 {
428 opt.min_version = SSL_MINOR_VERSION_2;
429 opt.max_version = SSL_MINOR_VERSION_2;
430 }
431 else if( strcmp( q, "tls1_2" ) == 0 )
432 {
433 opt.min_version = SSL_MINOR_VERSION_3;
434 opt.max_version = SSL_MINOR_VERSION_3;
435 }
436 else
437 goto usage;
438 }
Paul Bakker91ebfb52012-11-23 14:04:08 +0100439 else if( strcmp( p, "auth_mode" ) == 0 )
440 {
441 if( strcmp( q, "none" ) == 0 )
442 opt.auth_mode = SSL_VERIFY_NONE;
443 else if( strcmp( q, "optional" ) == 0 )
444 opt.auth_mode = SSL_VERIFY_OPTIONAL;
445 else if( strcmp( q, "required" ) == 0 )
446 opt.auth_mode = SSL_VERIFY_REQUIRED;
447 else
448 goto usage;
449 }
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200450 else if( strcmp( p, "max_frag_len" ) == 0 )
451 {
452 if( strcmp( q, "512" ) == 0 )
453 opt.mfl_code = SSL_MAX_FRAG_LEN_512;
454 else if( strcmp( q, "1024" ) == 0 )
455 opt.mfl_code = SSL_MAX_FRAG_LEN_1024;
456 else if( strcmp( q, "2048" ) == 0 )
457 opt.mfl_code = SSL_MAX_FRAG_LEN_2048;
458 else if( strcmp( q, "4096" ) == 0 )
459 opt.mfl_code = SSL_MAX_FRAG_LEN_4096;
460 else
461 goto usage;
462 }
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200463 else if( strcmp( p, "tickets" ) == 0 )
464 {
465 opt.tickets = atoi( q );
466 if( opt.tickets < 0 || opt.tickets > 1 )
467 goto usage;
468 }
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100469 else if( strcmp( p, "cache_max" ) == 0 )
470 {
471 opt.cache_max = atoi( q );
472 if( opt.cache_max < 0 )
473 goto usage;
474 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000475 else
476 goto usage;
477 }
478
Paul Bakkerc1516be2013-06-29 16:01:32 +0200479 if( opt.force_ciphersuite[0] > 0 )
480 {
481 const ssl_ciphersuite_t *ciphersuite_info;
482 ciphersuite_info = ssl_ciphersuite_from_id( opt.force_ciphersuite[0] );
483
Paul Bakker5b55b792013-07-19 13:43:43 +0200484 if( opt.max_version != -1 &&
485 ciphersuite_info->min_minor_ver > opt.max_version )
486 {
487 printf("forced ciphersuite not allowed with this protocol version\n");
488 ret = 2;
489 goto usage;
490 }
491 if( opt.min_version != -1 &&
Paul Bakkerc1516be2013-06-29 16:01:32 +0200492 ciphersuite_info->max_minor_ver < opt.min_version )
493 {
494 printf("forced ciphersuite not allowed with this protocol version\n");
495 ret = 2;
496 goto usage;
497 }
Paul Bakker5b55b792013-07-19 13:43:43 +0200498 if( opt.max_version > ciphersuite_info->max_minor_ver )
499 opt.max_version = ciphersuite_info->max_minor_ver;
500 if( opt.min_version < ciphersuite_info->min_minor_ver )
501 opt.min_version = ciphersuite_info->min_minor_ver;
Paul Bakkerc1516be2013-06-29 16:01:32 +0200502 }
503
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200504#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000505 /*
Paul Bakkerfbb17802013-04-17 19:10:21 +0200506 * Unhexify the pre-shared key if any is given
507 */
508 if( strlen( opt.psk ) )
509 {
510 unsigned char c;
511 size_t j;
512
513 if( strlen( opt.psk ) % 2 != 0 )
514 {
515 printf("pre-shared key not valid hex\n");
516 goto exit;
517 }
518
519 psk_len = strlen( opt.psk ) / 2;
520
521 for( j = 0; j < strlen( opt.psk ); j += 2 )
522 {
523 c = opt.psk[j];
524 if( c >= '0' && c <= '9' )
525 c -= '0';
526 else if( c >= 'a' && c <= 'f' )
527 c -= 'a' - 10;
528 else if( c >= 'A' && c <= 'F' )
529 c -= 'A' - 10;
530 else
531 {
532 printf("pre-shared key not valid hex\n");
533 goto exit;
534 }
535 psk[ j / 2 ] = c << 4;
536
537 c = opt.psk[j + 1];
538 if( c >= '0' && c <= '9' )
539 c -= '0';
540 else if( c >= 'a' && c <= 'f' )
541 c -= 'a' - 10;
542 else if( c >= 'A' && c <= 'F' )
543 c -= 'A' - 10;
544 else
545 {
546 printf("pre-shared key not valid hex\n");
547 goto exit;
548 }
549 psk[ j / 2 ] |= c;
550 }
551 }
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200552#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
Paul Bakkerfbb17802013-04-17 19:10:21 +0200553
554 /*
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000555 * 0. Initialize the RNG and the session data
556 */
557 printf( "\n . Seeding the random number generator..." );
558 fflush( stdout );
559
560 entropy_init( &entropy );
561 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
Paul Bakkeref3f8c72013-06-24 13:01:08 +0200562 (const unsigned char *) pers,
563 strlen( pers ) ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000564 {
565 printf( " failed\n ! ctr_drbg_init returned -0x%x\n", -ret );
566 goto exit;
567 }
568
569 printf( " ok\n" );
570
Paul Bakker36713e82013-09-17 13:25:29 +0200571#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000572 /*
573 * 1.1. Load the trusted CA
574 */
575 printf( " . Loading the CA root certificate ..." );
576 fflush( stdout );
577
578#if defined(POLARSSL_FS_IO)
579 if( strlen( opt.ca_path ) )
Paul Bakkerddf26b42013-09-18 13:46:23 +0200580 ret = x509_crt_parse_path( &cacert, opt.ca_path );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000581 else if( strlen( opt.ca_file ) )
Paul Bakkerddf26b42013-09-18 13:46:23 +0200582 ret = x509_crt_parse_file( &cacert, opt.ca_file );
583 else
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000584#endif
585#if defined(POLARSSL_CERTS_C)
Manuel Pégourié-Gonnard641de712013-09-25 13:23:33 +0200586 ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_list,
587 strlen( test_ca_list ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000588#else
589 {
590 ret = 1;
591 printf("POLARSSL_CERTS_C not defined.");
592 }
593#endif
594 if( ret < 0 )
595 {
Paul Bakkerddf26b42013-09-18 13:46:23 +0200596 printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000597 goto exit;
598 }
599
600 printf( " ok (%d skipped)\n", ret );
601
602 /*
603 * 1.2. Load own certificate and private key
604 */
605 printf( " . Loading the server cert. and key..." );
606 fflush( stdout );
607
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200608#if defined(POLARSSL_FS_IO)
609 if( strlen( opt.crt_file ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200610 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200611 key_cert_init++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200612 if( ( ret = x509_crt_parse_file( &srvcert, opt.crt_file ) ) != 0 )
613 {
614 printf( " failed\n ! x509_crt_parse_file returned -0x%x\n\n",
615 -ret );
616 goto exit;
617 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200618 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200619 if( strlen( opt.key_file ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200620 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200621 key_cert_init++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200622 if( ( ret = pk_parse_keyfile( &pkey, opt.key_file, "" ) ) != 0 )
623 {
624 printf( " failed\n ! pk_parse_keyfile returned -0x%x\n\n", -ret );
625 goto exit;
626 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200627 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200628 if( key_cert_init == 1 )
629 {
630 printf( " failed\n ! crt_file without key_file or vice-versa\n\n" );
631 goto exit;
632 }
633
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200634 if( strlen( opt.crt_file2 ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200635 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200636 key_cert_init2++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200637 if( ( ret = x509_crt_parse_file( &srvcert2, opt.crt_file2 ) ) != 0 )
638 {
639 printf( " failed\n ! x509_crt_parse_file(2) returned -0x%x\n\n",
640 -ret );
641 goto exit;
642 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200643 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200644 if( strlen( opt.key_file2 ) )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200645 {
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200646 key_cert_init2++;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200647 if( ( ret = pk_parse_keyfile( &pkey2, opt.key_file2, "" ) ) != 0 )
648 {
649 printf( " failed\n ! pk_parse_keyfile(2) returned -0x%x\n\n",
650 -ret );
651 goto exit;
652 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200653 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200654 if( key_cert_init2 == 1 )
655 {
656 printf( " failed\n ! crt_file2 without key_file2 or vice-versa\n\n" );
657 goto exit;
658 }
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200659#endif
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200660 if( key_cert_init == 0 && key_cert_init2 == 0 )
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200661 {
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200662#if !defined(POLARSSL_CERTS_C)
663 printf( "Not certificated or key provided, and \n"
664 "POLARSSL_CERTS_C not defined!\n" );
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200665 goto exit;
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200666#else
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200667#if defined(POLARSSL_RSA_C)
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200668 if( ( ret = x509_crt_parse( &srvcert,
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200669 (const unsigned char *) test_srv_crt_rsa,
670 strlen( test_srv_crt_rsa ) ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200671 {
672 printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
673 goto exit;
674 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200675 if( ( ret = pk_parse_key( &pkey,
676 (const unsigned char *) test_srv_key_rsa,
677 strlen( test_srv_key_rsa ), NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200678 {
679 printf( " failed\n ! pk_parse_key returned -0x%x\n\n", -ret );
680 goto exit;
681 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200682 key_cert_init = 2;
683#endif /* POLARSSL_RSA_C */
684#if defined(POLARSSL_ECDSA_C)
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200685 if( ( ret = x509_crt_parse( &srvcert2,
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200686 (const unsigned char *) test_srv_crt_ec,
687 strlen( test_srv_crt_ec ) ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200688 {
689 printf( " failed\n ! x509_crt_parse2 returned -0x%x\n\n", -ret );
690 goto exit;
691 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200692 if( ( ret = pk_parse_key( &pkey2,
693 (const unsigned char *) test_srv_key_ec,
694 strlen( test_srv_key_ec ), NULL, 0 ) ) != 0 )
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200695 {
696 printf( " failed\n ! pk_parse_key2 returned -0x%x\n\n", -ret );
697 goto exit;
698 }
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200699 key_cert_init2 = 2;
700#endif /* POLARSSL_ECDSA_C */
Manuel Pégourié-Gonnardac8474f2013-09-25 11:35:15 +0200701#endif /* POLARSSL_CERTS_C */
702 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000703
704 printf( " ok\n" );
Paul Bakker36713e82013-09-17 13:25:29 +0200705#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000706
707 /*
708 * 2. Setup the listening TCP socket
709 */
710 printf( " . Bind on tcp://localhost:%-4d/ ...", opt.server_port );
711 fflush( stdout );
712
Manuel Pégourié-Gonnard18d31f82013-12-13 16:21:41 +0100713 if( ( ret = net_bind( &listen_fd, opt.server_addr,
714 opt.server_port ) ) != 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000715 {
716 printf( " failed\n ! net_bind returned -0x%x\n\n", -ret );
717 goto exit;
718 }
719
720 printf( " ok\n" );
721
722 /*
723 * 3. Setup stuff
724 */
725 printf( " . Setting up the SSL/TLS structure..." );
726 fflush( stdout );
727
728 if( ( ret = ssl_init( &ssl ) ) != 0 )
729 {
730 printf( " failed\n ! ssl_init returned -0x%x\n\n", -ret );
731 goto exit;
732 }
733
734 ssl_set_endpoint( &ssl, SSL_IS_SERVER );
Paul Bakker91ebfb52012-11-23 14:04:08 +0100735 ssl_set_authmode( &ssl, opt.auth_mode );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000736
Paul Bakker05decb22013-08-15 13:33:48 +0200737#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH)
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200738 ssl_set_max_frag_len( &ssl, opt.mfl_code );
Paul Bakker05decb22013-08-15 13:33:48 +0200739#endif
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200740
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000741 ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
742 ssl_set_dbg( &ssl, my_debug, stdout );
743
Paul Bakker0a597072012-09-25 21:55:46 +0000744#if defined(POLARSSL_SSL_CACHE_C)
Manuel Pégourié-Gonnard4c883452014-02-20 21:32:41 +0100745 if( opt.cache_max != -1 )
746 ssl_cache_set_max_entries( &cache, opt.cache_max );
747
Paul Bakker0a597072012-09-25 21:55:46 +0000748 ssl_set_session_cache( &ssl, ssl_cache_get, &cache,
749 ssl_cache_set, &cache );
750#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000751
Paul Bakkera503a632013-08-14 13:48:06 +0200752#if defined(POLARSSL_SSL_SESSION_TICKETS)
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200753 ssl_set_session_tickets( &ssl, opt.tickets );
Paul Bakkera503a632013-08-14 13:48:06 +0200754#endif
Manuel Pégourié-Gonnardaa0d4d12013-08-03 13:02:31 +0200755
Paul Bakker41c83d32013-03-20 14:39:14 +0100756 if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000757 ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
758
759 ssl_set_renegotiation( &ssl, opt.renegotiation );
760 ssl_legacy_renegotiation( &ssl, opt.allow_legacy );
761
Paul Bakker36713e82013-09-17 13:25:29 +0200762#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000763 ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
Manuel Pégourié-Gonnarda0fdf8b2013-09-25 14:05:49 +0200764 if( key_cert_init )
765 ssl_set_own_cert( &ssl, &srvcert, &pkey );
766 if( key_cert_init2 )
767 ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
Manuel Pégourié-Gonnardb095a7b2013-09-24 21:14:51 +0200768#endif
Paul Bakkered27a042013-04-18 22:46:23 +0200769
Manuel Pégourié-Gonnard8a3c64d2013-10-14 19:54:10 +0200770#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
Paul Bakker3c5ef712013-06-25 16:37:45 +0200771 ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
Paul Bakkerfbb17802013-04-17 19:10:21 +0200772 strlen( opt.psk_identity ) );
Paul Bakkered27a042013-04-18 22:46:23 +0200773#endif
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000774
775#if defined(POLARSSL_DHM_C)
Paul Bakker5d19f862012-09-28 07:33:00 +0000776 /*
777 * Use different group than default DHM group
778 */
Paul Bakkerd4324102012-09-26 08:29:38 +0000779 ssl_set_dh_param( &ssl, POLARSSL_DHM_RFC5114_MODP_2048_P,
780 POLARSSL_DHM_RFC5114_MODP_2048_G );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000781#endif
782
Paul Bakker1d29fb52012-09-28 13:28:45 +0000783 if( opt.min_version != -1 )
784 ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, opt.min_version );
785
Paul Bakkerc1516be2013-06-29 16:01:32 +0200786 if( opt.max_version != -1 )
787 ssl_set_max_version( &ssl, SSL_MAJOR_VERSION_3, opt.max_version );
788
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000789 printf( " ok\n" );
790
791reset:
792#ifdef POLARSSL_ERROR_C
793 if( ret != 0 )
794 {
795 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +0200796 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000797 printf("Last error was: %d - %s\n\n", ret, error_buf );
798 }
799#endif
800
801 if( client_fd != -1 )
802 net_close( client_fd );
803
804 ssl_session_reset( &ssl );
805
806 /*
807 * 3. Wait until a client connects
808 */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000809 client_fd = -1;
810
811 printf( " . Waiting for a remote connection ..." );
812 fflush( stdout );
813
814 if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 )
815 {
816 printf( " failed\n ! net_accept returned -0x%x\n\n", -ret );
817 goto exit;
818 }
819
820 ssl_set_bio( &ssl, net_recv, &client_fd,
821 net_send, &client_fd );
822
823 printf( " ok\n" );
824
825 /*
826 * 4. Handshake
827 */
828 printf( " . Performing the SSL/TLS handshake..." );
829 fflush( stdout );
830
831 while( ( ret = ssl_handshake( &ssl ) ) != 0 )
832 {
833 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
834 {
835 printf( " failed\n ! ssl_handshake returned -0x%x\n\n", -ret );
Paul Bakker1d29fb52012-09-28 13:28:45 +0000836 goto reset;
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000837 }
838 }
839
Manuel Pégourié-Gonnardc580a002014-02-12 10:15:30 +0100840 printf( " ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
841 ssl_get_version( &ssl ), ssl_get_ciphersuite( &ssl ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000842
Paul Bakker36713e82013-09-17 13:25:29 +0200843#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000844 /*
845 * 5. Verify the server certificate
846 */
847 printf( " . Verifying peer X.509 certificate..." );
848
849 if( ( ret = ssl_get_verify_result( &ssl ) ) != 0 )
850 {
851 printf( " failed\n" );
852
Paul Bakkerb0550d92012-10-30 07:51:03 +0000853 if( !ssl_get_peer_cert( &ssl ) )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000854 printf( " ! no client certificate sent\n" );
855
856 if( ( ret & BADCERT_EXPIRED ) != 0 )
857 printf( " ! client certificate has expired\n" );
858
859 if( ( ret & BADCERT_REVOKED ) != 0 )
860 printf( " ! client certificate has been revoked\n" );
861
862 if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
863 printf( " ! self-signed or not signed by a trusted CA\n" );
864
865 printf( "\n" );
866 }
867 else
868 printf( " ok\n" );
869
Paul Bakkerb0550d92012-10-30 07:51:03 +0000870 if( ssl_get_peer_cert( &ssl ) )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000871 {
872 printf( " . Peer certificate information ...\n" );
Paul Bakkerddf26b42013-09-18 13:46:23 +0200873 x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ",
874 ssl_get_peer_cert( &ssl ) );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000875 printf( "%s\n", buf );
876 }
Paul Bakker36713e82013-09-17 13:25:29 +0200877#endif /* POLARSSL_X509_CRT_PARSE_C */
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000878
879 /*
880 * 6. Read the HTTP Request
881 */
882 printf( " < Read from client:" );
883 fflush( stdout );
884
885 do
886 {
887 len = sizeof( buf ) - 1;
888 memset( buf, 0, sizeof( buf ) );
889 ret = ssl_read( &ssl, buf, len );
890
891 if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
892 continue;
893
894 if( ret <= 0 )
895 {
896 switch( ret )
897 {
898 case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
899 printf( " connection was closed gracefully\n" );
900 break;
901
902 case POLARSSL_ERR_NET_CONN_RESET:
903 printf( " connection was reset by peer\n" );
904 break;
905
906 default:
907 printf( " ssl_read returned -0x%x\n", -ret );
908 break;
909 }
910
911 break;
912 }
913
914 len = ret;
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200915 printf( " %d bytes read\n\n%s\n", len, (char *) buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000916
Paul Bakker82024bf2013-07-04 11:52:32 +0200917 if( memcmp( buf, "SERVERQUIT", 10 ) == 0 )
Manuel Pégourié-Gonnarde8ea0c02013-09-07 17:09:14 +0200918 {
919 ret = 0;
Paul Bakker82024bf2013-07-04 11:52:32 +0200920 goto exit;
Manuel Pégourié-Gonnarde8ea0c02013-09-07 17:09:14 +0200921 }
Paul Bakker82024bf2013-07-04 11:52:32 +0200922
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000923 if( ret > 0 )
924 break;
925 }
926 while( 1 );
927
928 /*
929 * 7. Write the 200 Response
930 */
931 printf( " > Write to client:" );
932 fflush( stdout );
933
934 len = sprintf( (char *) buf, HTTP_RESPONSE,
935 ssl_get_ciphersuite( &ssl ) );
936
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200937 for( written = 0, frags = 0; written < len; written += ret, frags++ )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000938 {
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200939 while( ( ret = ssl_write( &ssl, buf + written, len - written ) ) <= 0 )
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000940 {
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200941 if( ret == POLARSSL_ERR_NET_CONN_RESET )
942 {
943 printf( " failed\n ! peer closed the connection\n\n" );
944 goto reset;
945 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000946
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200947 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
948 {
949 printf( " failed\n ! ssl_write returned %d\n\n", ret );
950 goto exit;
951 }
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000952 }
953 }
954
Manuel Pégourié-Gonnardbd7ce632013-07-17 15:34:17 +0200955 buf[written] = '\0';
Manuel Pégourié-Gonnard0c017a52013-07-18 14:07:36 +0200956 printf( " %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf );
Paul Bakkerb60b95f2012-09-25 09:05:17 +0000957
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100958 if( opt.renegotiate )
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +0100959 {
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100960 /*
961 * Request renegotiation (this must be done when the client is still
962 * waiting for input from our side).
963 */
964 printf( " . Requestion renegotiation..." );
965 fflush( stdout );
966 while( ( ret = ssl_renegotiate( &ssl ) ) != 0 )
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +0100967 {
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100968 if( ret != POLARSSL_ERR_NET_WANT_READ &&
969 ret != POLARSSL_ERR_NET_WANT_WRITE )
970 {
971 printf( " failed\n ! ssl_renegotiate returned %d\n\n", ret );
Manuel Pégourié-Gonnard6d8404d2013-10-30 16:41:45 +0100972 goto exit;
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100973 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +0100974 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +0100975
Manuel Pégourié-Gonnard780d6712014-02-20 17:19:59 +0100976 /*
977 * Should be a while loop, not an if, but here we're not actually
978 * expecting data from the client, and since we're running tests
979 * locally, we can just hope the handshake will finish the during the
980 * first call.
981 */
982 if( ( ret = ssl_read( &ssl, buf, 0 ) ) != 0 )
983 {
984 if( ret != POLARSSL_ERR_NET_WANT_READ &&
985 ret != POLARSSL_ERR_NET_WANT_WRITE )
986 {
987 printf( " failed\n ! ssl_read returned %d\n\n", ret );
988
989 /* Unexpected message probably means client didn't renegotiate
990 * as requested */
991 if( ret == POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE )
992 goto reset;
993 else
994 goto exit;
995 }
996 }
997
998 printf( " ok\n" );
999 }
Manuel Pégourié-Gonnardf3dc2f62013-10-29 18:17:41 +01001000
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001001 ret = 0;
1002 goto reset;
1003
1004exit:
1005
1006#ifdef POLARSSL_ERROR_C
1007 if( ret != 0 )
1008 {
1009 char error_buf[100];
Paul Bakker03a8a792013-06-30 12:18:08 +02001010 polarssl_strerror( ret, error_buf, 100 );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001011 printf("Last error was: -0x%X - %s\n\n", -ret, error_buf );
1012 }
1013#endif
1014
1015 net_close( client_fd );
Paul Bakker36713e82013-09-17 13:25:29 +02001016#if defined(POLARSSL_X509_CRT_PARSE_C)
Paul Bakker36713e82013-09-17 13:25:29 +02001017 x509_crt_free( &cacert );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +02001018 x509_crt_free( &srvcert );
Manuel Pégourié-Gonnardac755232013-08-19 14:10:16 +02001019 pk_free( &pkey );
Manuel Pégourié-Gonnard3ebb2cd2013-09-23 17:00:18 +02001020 x509_crt_free( &srvcert2 );
1021 pk_free( &pkey2 );
Paul Bakkered27a042013-04-18 22:46:23 +02001022#endif
1023
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001024 ssl_free( &ssl );
Paul Bakker1ffefac2013-09-28 15:23:03 +02001025 entropy_free( &entropy );
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001026
Paul Bakker0a597072012-09-25 21:55:46 +00001027#if defined(POLARSSL_SSL_CACHE_C)
1028 ssl_cache_free( &cache );
1029#endif
1030
Paul Bakker1337aff2013-09-29 14:45:34 +02001031#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
1032#if defined(POLARSSL_MEMORY_DEBUG)
Paul Bakker82024bf2013-07-04 11:52:32 +02001033 memory_buffer_alloc_status();
1034#endif
Paul Bakker1337aff2013-09-29 14:45:34 +02001035 memory_buffer_alloc_free();
1036#endif
Paul Bakker82024bf2013-07-04 11:52:32 +02001037
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001038#if defined(_WIN32)
1039 printf( " + Press Enter to exit this program.\n" );
1040 fflush( stdout ); getchar();
1041#endif
1042
Paul Bakkerdbd79ca2013-07-24 16:28:35 +02001043 // Shell can not handle large exit numbers -> 1 for errors
1044 if( ret < 0 )
1045 ret = 1;
1046
Paul Bakkerb60b95f2012-09-25 09:05:17 +00001047 return( ret );
1048}
1049#endif /* POLARSSL_BIGNUM_C && POLARSSL_ENTROPY_C && POLARSSL_SSL_TLS_C &&
1050 POLARSSL_SSL_SRV_C && POLARSSL_NET_C && POLARSSL_RSA_C &&
1051 POLARSSL_CTR_DRBG_C */