blob: ca84c7a0ae858fd262c03fa0c7e90a71cf81662e [file] [log] [blame]
Paul Bakkerf9c49532013-12-19 15:40:58 +01001/*
2 * SSL server demonstration program using pthread for handling multiple
3 * clients.
4 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02005 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02006 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
Paul Bakkerf9c49532013-12-19 15:40:58 +010019 */
20
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020021#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000022#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020023#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020025#endif
Paul Bakkerf9c49532013-12-19 15:40:58 +010026
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000027#include "mbedtls/platform.h"
Rich Evansf90016a2015-01-19 14:26:37 +000028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_CERTS_C) || \
30 !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_SSL_TLS_C) || \
31 !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) || \
32 !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
33 !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
34 !defined(MBEDTLS_THREADING_C) || !defined(MBEDTLS_THREADING_PTHREAD) || \
35 !defined(MBEDTLS_PEM_PARSE_C)
Rich Evans85b05ec2015-02-12 11:37:29 +000036int main( void )
Paul Bakkerf9c49532013-12-19 15:40:58 +010037{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038 mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or MBEDTLS_ENTROPY_C "
39 "and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
40 "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
41 "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
42 "MBEDTLS_THREADING_C and/or MBEDTLS_THREADING_PTHREAD "
43 "and/or MBEDTLS_PEM_PARSE_C not defined.\n");
Krzysztof Stachowiak5e1b1952019-04-24 14:24:46 +020044 mbedtls_exit( 0 );
Paul Bakkerf9c49532013-12-19 15:40:58 +010045}
46#else
Manuel Pégourié-Gonnard4b3e5ef2015-03-27 11:24:27 +010047
48#include <stdlib.h>
49#include <string.h>
50
51#if defined(_WIN32)
52#include <windows.h>
53#endif
54
55#include "mbedtls/entropy.h"
56#include "mbedtls/ctr_drbg.h"
57#include "mbedtls/certs.h"
58#include "mbedtls/x509.h"
59#include "mbedtls/ssl.h"
Andres AG788aa4a2016-09-14 14:32:09 +010060#include "mbedtls/net_sockets.h"
Manuel Pégourié-Gonnard4b3e5ef2015-03-27 11:24:27 +010061#include "mbedtls/error.h"
62
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_SSL_CACHE_C)
Manuel Pégourié-Gonnard4b3e5ef2015-03-27 11:24:27 +010064#include "mbedtls/ssl_cache.h"
65#endif
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Manuel Pégourié-Gonnard4b3e5ef2015-03-27 11:24:27 +010068#include "mbedtls/memory_buffer_alloc.h"
69#endif
70
Manuel Pégourié-Gonnard3ef6a6d2018-12-10 14:31:45 +010071
Manuel Pégourié-Gonnard4b3e5ef2015-03-27 11:24:27 +010072#define HTTP_RESPONSE \
73 "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
74 "<h2>mbed TLS Test Server</h2>\r\n" \
75 "<p>Successful connection using: %s</p>\r\n"
76
77#define DEBUG_LEVEL 0
78
79#define MAX_NUM_THREADS 5
80
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081mbedtls_threading_mutex_t debug_mutex;
Paul Bakkerf9c49532013-12-19 15:40:58 +010082
Manuel Pégourié-Gonnard61ee3512015-06-23 17:35:03 +020083static void my_mutexed_debug( void *ctx, int level,
84 const char *file, int line,
85 const char *str )
Paul Bakkerf9c49532013-12-19 15:40:58 +010086{
Manuel Pégourié-Gonnard61ee3512015-06-23 17:35:03 +020087 long int thread_id = (long int) pthread_self();
88
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020089 mbedtls_mutex_lock( &debug_mutex );
Manuel Pégourié-Gonnard61ee3512015-06-23 17:35:03 +020090
91 ((void) level);
92 mbedtls_fprintf( (FILE *) ctx, "%s:%04d: [ #%ld ] %s",
93 file, line, thread_id, str );
94 fflush( (FILE *) ctx );
95
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096 mbedtls_mutex_unlock( &debug_mutex );
Paul Bakkerf9c49532013-12-19 15:40:58 +010097}
98
99typedef struct {
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200100 mbedtls_net_context client_fd;
Paul Bakkerf9c49532013-12-19 15:40:58 +0100101 int thread_complete;
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200102 const mbedtls_ssl_config *config;
Paul Bakkerf9c49532013-12-19 15:40:58 +0100103} thread_info_t;
104
105typedef struct {
106 int active;
107 thread_info_t data;
108 pthread_t thread;
109} pthread_info_t;
110
Paul Bakkerf9c49532013-12-19 15:40:58 +0100111static thread_info_t base_info;
112static pthread_info_t threads[MAX_NUM_THREADS];
113
114static void *handle_ssl_connection( void *data )
115{
116 int ret, len;
117 thread_info_t *thread_info = (thread_info_t *) data;
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200118 mbedtls_net_context *client_fd = &thread_info->client_fd;
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200119 long int thread_id = (long int) pthread_self();
Paul Bakkerf9c49532013-12-19 15:40:58 +0100120 unsigned char buf[1024];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121 mbedtls_ssl_context ssl;
Paul Bakkerf9c49532013-12-19 15:40:58 +0100122
Manuel Pégourié-Gonnard955028f2014-07-12 01:27:34 +0200123 /* Make sure memory references are valid */
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +0200124 mbedtls_ssl_init( &ssl );
Manuel Pégourié-Gonnard955028f2014-07-12 01:27:34 +0200125
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200126 mbedtls_printf( " [ #%ld ] Setting up SSL/TLS data\n", thread_id );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100127
128 /*
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200129 * 4. Get the SSL context ready
Paul Bakkerf9c49532013-12-19 15:40:58 +0100130 */
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200131 if( ( ret = mbedtls_ssl_setup( &ssl, thread_info->config ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100132 {
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200133 mbedtls_printf( " [ #%ld ] failed: mbedtls_ssl_setup returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000134 thread_id, ( unsigned int ) -ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100135 goto thread_exit;
136 }
137
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200138 mbedtls_ssl_set_bio( &ssl, client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100139
Paul Bakkerf9c49532013-12-19 15:40:58 +0100140 /*
141 * 5. Handshake
142 */
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200143 mbedtls_printf( " [ #%ld ] Performing the SSL/TLS handshake\n", thread_id );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100146 {
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100147 if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100148 {
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200149 mbedtls_printf( " [ #%ld ] failed: mbedtls_ssl_handshake returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000150 thread_id, ( unsigned int ) -ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100151 goto thread_exit;
152 }
153 }
154
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200155 mbedtls_printf( " [ #%ld ] ok\n", thread_id );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100156
157 /*
158 * 6. Read the HTTP Request
159 */
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200160 mbedtls_printf( " [ #%ld ] < Read from client\n", thread_id );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100161
162 do
163 {
164 len = sizeof( buf ) - 1;
165 memset( buf, 0, sizeof( buf ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166 ret = mbedtls_ssl_read( &ssl, buf, len );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100167
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100168 if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100169 continue;
170
171 if( ret <= 0 )
172 {
173 switch( ret )
174 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200176 mbedtls_printf( " [ #%ld ] connection was closed gracefully\n",
Paul Bakkerf9c49532013-12-19 15:40:58 +0100177 thread_id );
178 goto thread_exit;
179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 case MBEDTLS_ERR_NET_CONN_RESET:
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200181 mbedtls_printf( " [ #%ld ] connection was reset by peer\n",
Paul Bakkerf9c49532013-12-19 15:40:58 +0100182 thread_id );
183 goto thread_exit;
184
185 default:
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200186 mbedtls_printf( " [ #%ld ] mbedtls_ssl_read returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000187 thread_id, ( unsigned int ) -ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100188 goto thread_exit;
189 }
Paul Bakkerf9c49532013-12-19 15:40:58 +0100190 }
191
192 len = ret;
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200193 mbedtls_printf( " [ #%ld ] %d bytes read\n=====\n%s\n=====\n",
Paul Bakkerf9c49532013-12-19 15:40:58 +0100194 thread_id, len, (char *) buf );
195
196 if( ret > 0 )
197 break;
198 }
199 while( 1 );
200
201 /*
202 * 7. Write the 200 Response
203 */
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200204 mbedtls_printf( " [ #%ld ] > Write to client:\n", thread_id );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100205
206 len = sprintf( (char *) buf, HTTP_RESPONSE,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 mbedtls_ssl_get_ciphersuite( &ssl ) );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100210 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 if( ret == MBEDTLS_ERR_NET_CONN_RESET )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100212 {
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200213 mbedtls_printf( " [ #%ld ] failed: peer closed the connection\n",
Paul Bakkerf9c49532013-12-19 15:40:58 +0100214 thread_id );
215 goto thread_exit;
216 }
217
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100218 if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100219 {
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200220 mbedtls_printf( " [ #%ld ] failed: mbedtls_ssl_write returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000221 thread_id, ( unsigned int ) ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100222 goto thread_exit;
223 }
224 }
225
226 len = ret;
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200227 mbedtls_printf( " [ #%ld ] %d bytes written\n=====\n%s\n=====\n",
Paul Bakkerf9c49532013-12-19 15:40:58 +0100228 thread_id, len, (char *) buf );
229
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200230 mbedtls_printf( " [ #%ld ] . Closing the connection...", thread_id );
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +0100231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 while( ( ret = mbedtls_ssl_close_notify( &ssl ) ) < 0 )
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +0100233 {
Manuel Pégourié-Gonnard88369942015-05-06 16:19:31 +0100234 if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
235 ret != MBEDTLS_ERR_SSL_WANT_WRITE )
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +0100236 {
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200237 mbedtls_printf( " [ #%ld ] failed: mbedtls_ssl_close_notify returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000238 thread_id, ( unsigned int ) ret );
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +0100239 goto thread_exit;
240 }
241 }
242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243 mbedtls_printf( " ok\n" );
Manuel Pégourié-Gonnard6b0d2682014-03-25 11:24:43 +0100244
Paul Bakkerf9c49532013-12-19 15:40:58 +0100245 ret = 0;
246
247thread_exit:
248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249#ifdef MBEDTLS_ERROR_C
Paul Bakkerf9c49532013-12-19 15:40:58 +0100250 if( ret != 0 )
251 {
252 char error_buf[100];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 mbedtls_strerror( ret, error_buf, 100 );
Manuel Pégourié-Gonnard30eceb72015-05-11 14:42:56 +0200254 mbedtls_printf(" [ #%ld ] Last error was: -0x%04x - %s\n\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000255 thread_id, ( unsigned int ) -ret, error_buf );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100256 }
257#endif
258
Manuel Pégourié-Gonnard3d7d00a2015-06-30 15:55:03 +0200259 mbedtls_net_free( client_fd );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 mbedtls_ssl_free( &ssl );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100261
262 thread_info->thread_complete = 1;
263
264 return( NULL );
265}
266
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200267static int thread_create( mbedtls_net_context *client_fd )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100268{
269 int ret, i;
270
271 /*
272 * Find in-active or finished thread slot
273 */
274 for( i = 0; i < MAX_NUM_THREADS; i++ )
275 {
276 if( threads[i].active == 0 )
277 break;
278
279 if( threads[i].data.thread_complete == 1 )
280 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281 mbedtls_printf( " [ main ] Cleaning up thread %d\n", i );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100282 pthread_join(threads[i].thread, NULL );
283 memset( &threads[i], 0, sizeof(pthread_info_t) );
284 break;
285 }
286 }
287
288 if( i == MAX_NUM_THREADS )
289 return( -1 );
290
291 /*
292 * Fill thread-info for thread
293 */
294 memcpy( &threads[i].data, &base_info, sizeof(base_info) );
295 threads[i].active = 1;
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200296 memcpy( &threads[i].data.client_fd, client_fd, sizeof( mbedtls_net_context ) );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100297
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200298 if( ( ret = pthread_create( &threads[i].thread, NULL, handle_ssl_connection,
299 &threads[i].data ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100300 {
301 return( ret );
302 }
303
304 return( 0 );
305}
306
Rich Evans85b05ec2015-02-12 11:37:29 +0000307int main( void )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100308{
309 int ret;
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200310 mbedtls_net_context listen_fd, client_fd;
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200311 const char pers[] = "ssl_pthread_server";
Paul Bakkerf9c49532013-12-19 15:40:58 +0100312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 mbedtls_entropy_context entropy;
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200314 mbedtls_ctr_drbg_context ctr_drbg;
315 mbedtls_ssl_config conf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316 mbedtls_x509_crt srvcert;
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200317 mbedtls_x509_crt cachain;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318 mbedtls_pk_context pkey;
319#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Paul Bakkerf9c49532013-12-19 15:40:58 +0100320 unsigned char alloc_buf[100000];
321#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322#if defined(MBEDTLS_SSL_CACHE_C)
323 mbedtls_ssl_cache_context cache;
Paul Bakkerf9c49532013-12-19 15:40:58 +0100324#endif
325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
327 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100328#endif
329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330#if defined(MBEDTLS_SSL_CACHE_C)
331 mbedtls_ssl_cache_init( &cache );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100332#endif
333
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200334 mbedtls_x509_crt_init( &srvcert );
335 mbedtls_x509_crt_init( &cachain );
336
337 mbedtls_ssl_config_init( &conf );
338 mbedtls_ctr_drbg_init( &ctr_drbg );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100339 memset( threads, 0, sizeof(threads) );
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200340 mbedtls_net_init( &listen_fd );
341 mbedtls_net_init( &client_fd );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 mbedtls_mutex_init( &debug_mutex );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100344
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200345 base_info.config = &conf;
346
Paul Bakkerf9c49532013-12-19 15:40:58 +0100347 /*
348 * We use only a single entropy source that is used in all the threads.
349 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_entropy_init( &entropy );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100351
352 /*
353 * 1. Load the certificates and private RSA key
354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_printf( "\n . Loading the server cert. and key..." );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100356 fflush( stdout );
357
Paul Bakkerf9c49532013-12-19 15:40:58 +0100358 /*
359 * This demonstration program uses embedded test certificates.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the
361 * server and CA certificates, as well as mbedtls_pk_parse_keyfile().
Paul Bakkerf9c49532013-12-19 15:40:58 +0100362 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) mbedtls_test_srv_crt,
364 mbedtls_test_srv_crt_len );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100365 if( ret != 0 )
366 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100368 goto exit;
369 }
370
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200371 ret = mbedtls_x509_crt_parse( &cachain, (const unsigned char *) mbedtls_test_cas_pem,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 mbedtls_test_cas_pem_len );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100373 if( ret != 0 )
374 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100376 goto exit;
377 }
378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_pk_init( &pkey );
380 ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key,
381 mbedtls_test_srv_key_len, NULL, 0 );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100382 if( ret != 0 )
383 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 mbedtls_printf( " failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100385 goto exit;
386 }
387
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200388 mbedtls_printf( " ok\n" );
389
390 /*
391 * 1b. Seed the random number generator
392 */
393 mbedtls_printf( " . Seeding the random number generator..." );
394
395 if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
396 (const unsigned char *) pers,
397 strlen( pers ) ) ) != 0 )
398 {
399 mbedtls_printf( " failed: mbedtls_ctr_drbg_seed returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000400 ( unsigned int ) -ret );
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200401 goto exit;
402 }
Paul Bakkerf9c49532013-12-19 15:40:58 +0100403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_printf( " ok\n" );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100405
406 /*
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200407 * 1c. Prepare SSL configuration
408 */
409 mbedtls_printf( " . Setting up the SSL data...." );
410
411 if( ( ret = mbedtls_ssl_config_defaults( &conf,
412 MBEDTLS_SSL_IS_SERVER,
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +0200413 MBEDTLS_SSL_TRANSPORT_STREAM,
414 MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200415 {
416 mbedtls_printf( " failed: mbedtls_ssl_config_defaults returned -0x%04x\n",
Paul Elliott29b64162021-03-17 13:02:02 +0000417 ( unsigned int ) -ret );
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200418 goto exit;
419 }
420
421 mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
422 mbedtls_ssl_conf_dbg( &conf, my_mutexed_debug, stdout );
423
424 /* mbedtls_ssl_cache_get() and mbedtls_ssl_cache_set() are thread-safe if
425 * MBEDTLS_THREADING_C is set.
426 */
427#if defined(MBEDTLS_SSL_CACHE_C)
428 mbedtls_ssl_conf_session_cache( &conf, &cache,
429 mbedtls_ssl_cache_get,
430 mbedtls_ssl_cache_set );
431#endif
432
433 mbedtls_ssl_conf_ca_chain( &conf, &cachain, NULL );
434 if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
435 {
436 mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
437 goto exit;
438 }
439
440 mbedtls_printf( " ok\n" );
441
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200442 /*
Paul Bakkerf9c49532013-12-19 15:40:58 +0100443 * 2. Setup the listening TCP socket
444 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 mbedtls_printf( " . Bind on https://localhost:4433/ ..." );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100446 fflush( stdout );
447
Manuel Pégourié-Gonnardc0d74942015-06-23 12:30:57 +0200448 if( ( ret = mbedtls_net_bind( &listen_fd, NULL, "4433", MBEDTLS_NET_PROTO_TCP ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100449 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 mbedtls_printf( " failed\n ! mbedtls_net_bind returned %d\n\n", ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100451 goto exit;
452 }
453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_printf( " ok\n" );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100455
456reset:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457#ifdef MBEDTLS_ERROR_C
Paul Bakkerf9c49532013-12-19 15:40:58 +0100458 if( ret != 0 )
459 {
460 char error_buf[100];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_strerror( ret, error_buf, 100 );
Paul Elliott29b64162021-03-17 13:02:02 +0000462 mbedtls_printf( " [ main ] Last error was: -0x%04x - %s\n", ( unsigned int ) -ret,
463 error_buf );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100464 }
465#endif
466
467 /*
468 * 3. Wait until a client connects
469 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_printf( " [ main ] Waiting for a remote connection\n" );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100471
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200472 if( ( ret = mbedtls_net_accept( &listen_fd, &client_fd,
Manuel Pégourié-Gonnard0b104b02015-05-14 21:52:40 +0200473 NULL, 0, NULL ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100474 {
Paul Elliott29b64162021-03-17 13:02:02 +0000475 mbedtls_printf( " [ main ] failed: mbedtls_net_accept returned -0x%04x\n",
476 ( unsigned int ) ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100477 goto exit;
478 }
479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 mbedtls_printf( " [ main ] ok\n" );
481 mbedtls_printf( " [ main ] Creating a new thread\n" );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100482
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200483 if( ( ret = thread_create( &client_fd ) ) != 0 )
Paul Bakkerf9c49532013-12-19 15:40:58 +0100484 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 mbedtls_printf( " [ main ] failed: thread_create returned %d\n", ret );
Manuel Pégourié-Gonnard3d7d00a2015-06-30 15:55:03 +0200486 mbedtls_net_free( &client_fd );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100487 goto reset;
488 }
489
490 ret = 0;
491 goto reset;
492
493exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_x509_crt_free( &srvcert );
495 mbedtls_pk_free( &pkey );
496#if defined(MBEDTLS_SSL_CACHE_C)
497 mbedtls_ssl_cache_free( &cache );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100498#endif
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200499 mbedtls_ctr_drbg_free( &ctr_drbg );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500 mbedtls_entropy_free( &entropy );
Manuel Pégourié-Gonnard0af00e82015-05-11 11:32:43 +0200501 mbedtls_ssl_config_free( &conf );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100502
Manuel Pégourié-Gonnard5db64322015-06-30 15:40:39 +0200503 mbedtls_net_free( &listen_fd );
504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 mbedtls_mutex_free( &debug_mutex );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
508 mbedtls_memory_buffer_alloc_free();
Paul Bakkerf9c49532013-12-19 15:40:58 +0100509#endif
510
511#if defined(_WIN32)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_printf( " Press Enter to exit this program.\n" );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100513 fflush( stdout ); getchar();
514#endif
515
Krzysztof Stachowiak5e1b1952019-04-24 14:24:46 +0200516 mbedtls_exit( ret );
Paul Bakkerf9c49532013-12-19 15:40:58 +0100517}
518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_CERTS_C && MBEDTLS_ENTROPY_C &&
520 MBEDTLS_SSL_TLS_C && MBEDTLS_SSL_SRV_C && MBEDTLS_NET_C &&
521 MBEDTLS_RSA_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_THREADING_C &&
522 MBEDTLS_THREADING_PTHREAD && MBEDTLS_PEM_PARSE_C */