| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | *  SSL server demonstration program using pthread for handling multiple | 
|  | 3 | *  clients. | 
|  | 4 | * | 
| Manuel Pégourié-Gonnard | a658a40 | 2015-01-23 09:45:19 +0000 | [diff] [blame] | 5 | *  Copyright (C) 2006-2013, ARM Limited, All Rights Reserved | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 6 | * | 
| Manuel Pégourié-Gonnard | 860b516 | 2015-01-28 17:12:07 +0000 | [diff] [blame] | 7 | *  This file is part of mbed TLS (https://polarssl.org) | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 8 | * | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 9 | *  This program is free software; you can redistribute it and/or modify | 
|  | 10 | *  it under the terms of the GNU General Public License as published by | 
|  | 11 | *  the Free Software Foundation; either version 2 of the License, or | 
|  | 12 | *  (at your option) any later version. | 
|  | 13 | * | 
|  | 14 | *  This program is distributed in the hope that it will be useful, | 
|  | 15 | *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 16 | *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 17 | *  GNU General Public License for more details. | 
|  | 18 | * | 
|  | 19 | *  You should have received a copy of the GNU General Public License along | 
|  | 20 | *  with this program; if not, write to the Free Software Foundation, Inc., | 
|  | 21 | *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 
|  | 22 | */ | 
|  | 23 |  | 
| Manuel Pégourié-Gonnard | cef4ad2 | 2014-04-29 12:39:06 +0200 | [diff] [blame] | 24 | #if !defined(POLARSSL_CONFIG_FILE) | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 25 | #include "polarssl/config.h" | 
| Manuel Pégourié-Gonnard | cef4ad2 | 2014-04-29 12:39:06 +0200 | [diff] [blame] | 26 | #else | 
|  | 27 | #include POLARSSL_CONFIG_FILE | 
|  | 28 | #endif | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 29 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 30 | #if defined(POLARSSL_PLATFORM_C) | 
|  | 31 | #include "polarssl/platform.h" | 
|  | 32 | #else | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 33 | #include <stdio.h> | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 34 | #define polarssl_fprintf    fprintf | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 35 | #define polarssl_printf     printf | 
| Manuel Pégourié-Gonnard | ac1f76c | 2015-02-13 15:11:24 +0000 | [diff] [blame] | 36 | #define polarssl_snprintf   snprintf | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 37 | #endif | 
|  | 38 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 39 | #if defined(_WIN32) | 
|  | 40 | #include <windows.h> | 
|  | 41 | #endif | 
|  | 42 |  | 
| Manuel Pégourié-Gonnard | 013bffe | 2015-02-13 14:09:44 +0000 | [diff] [blame] | 43 | #if defined(POLARSSL_BIGNUM_C) && defined(POLARSSL_CERTS_C) && \ | 
|  | 44 | defined(POLARSSL_ENTROPY_C) && defined(POLARSSL_SSL_TLS_C) && \ | 
|  | 45 | defined(POLARSSL_SSL_SRV_C) && defined(POLARSSL_NET_C) && \ | 
|  | 46 | defined(POLARSSL_RSA_C) && defined(POLARSSL_CTR_DRBG_C) && \ | 
|  | 47 | defined(POLARSSL_X509_CRT_PARSE_C) && defined(POLARSSL_FS_IO) && \ | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 48 | defined(POLARSSL_THREADING_C) && defined(POLARSSL_THREADING_PTHREAD) | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 49 | #include "polarssl/entropy.h" | 
|  | 50 | #include "polarssl/ctr_drbg.h" | 
|  | 51 | #include "polarssl/certs.h" | 
|  | 52 | #include "polarssl/x509.h" | 
|  | 53 | #include "polarssl/ssl.h" | 
|  | 54 | #include "polarssl/net.h" | 
|  | 55 | #include "polarssl/error.h" | 
|  | 56 |  | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 57 | #include <stdio.h> | 
|  | 58 | #include <stdlib.h> | 
|  | 59 | #include <string.h> | 
|  | 60 | #endif | 
|  | 61 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 62 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 63 | #include "polarssl/ssl_cache.h" | 
|  | 64 | #endif | 
|  | 65 |  | 
|  | 66 | #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) | 
| Manuel Pégourié-Gonnard | d43ccb6 | 2015-01-23 17:38:09 +0000 | [diff] [blame] | 67 | #include "polarssl/memory_buffer_alloc.h" | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 68 | #endif | 
|  | 69 |  | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 70 | #define HTTP_RESPONSE \ | 
|  | 71 | "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \ | 
|  | 72 | "<h2>mbed TLS Test Server</h2>\r\n" \ | 
|  | 73 | "<p>Successful connection using: %s</p>\r\n" | 
|  | 74 |  | 
|  | 75 | #define DEBUG_LEVEL 0 | 
|  | 76 |  | 
| Rich Evans | 85b05ec | 2015-02-12 11:37:29 +0000 | [diff] [blame] | 77 | #define MAX_NUM_THREADS 5 | 
|  | 78 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 79 | #if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_CERTS_C) ||            \ | 
|  | 80 | !defined(POLARSSL_ENTROPY_C) || !defined(POLARSSL_SSL_TLS_C) ||         \ | 
|  | 81 | !defined(POLARSSL_SSL_SRV_C) || !defined(POLARSSL_NET_C) ||             \ | 
|  | 82 | !defined(POLARSSL_RSA_C) || !defined(POLARSSL_CTR_DRBG_C) ||            \ | 
| Rich Evans | 18b78c7 | 2015-02-11 14:06:19 +0000 | [diff] [blame] | 83 | !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_FS_IO) ||      \ | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 84 | !defined(POLARSSL_THREADING_C) || !defined(POLARSSL_THREADING_PTHREAD) | 
| Rich Evans | 85b05ec | 2015-02-12 11:37:29 +0000 | [diff] [blame] | 85 | int main( void ) | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 86 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 87 | polarssl_printf("POLARSSL_BIGNUM_C and/or POLARSSL_CERTS_C and/or POLARSSL_ENTROPY_C " | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 88 | "and/or POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_SRV_C and/or " | 
|  | 89 | "POLARSSL_NET_C and/or POLARSSL_RSA_C and/or " | 
|  | 90 | "POLARSSL_CTR_DRBG_C and/or POLARSSL_X509_CRT_PARSE_C and/or " | 
|  | 91 | "POLARSSL_THREADING_C and/or POLARSSL_THREADING_PTHREAD " | 
|  | 92 | "not defined.\n"); | 
|  | 93 | return( 0 ); | 
|  | 94 | } | 
|  | 95 | #else | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 96 | threading_mutex_t debug_mutex; | 
|  | 97 |  | 
|  | 98 | static void my_mutexed_debug( void *ctx, int level, const char *str ) | 
|  | 99 | { | 
|  | 100 | polarssl_mutex_lock( &debug_mutex ); | 
|  | 101 | if( level < DEBUG_LEVEL ) | 
|  | 102 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 103 | polarssl_fprintf( (FILE *) ctx, "%s", str ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 104 | fflush(  (FILE *) ctx  ); | 
|  | 105 | } | 
|  | 106 | polarssl_mutex_unlock( &debug_mutex ); | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | typedef struct { | 
|  | 110 | int client_fd; | 
|  | 111 | int thread_complete; | 
|  | 112 | entropy_context *entropy; | 
|  | 113 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 114 | ssl_cache_context *cache; | 
|  | 115 | #endif | 
|  | 116 | x509_crt *ca_chain; | 
|  | 117 | x509_crt *server_cert; | 
|  | 118 | pk_context *server_key; | 
|  | 119 | } thread_info_t; | 
|  | 120 |  | 
|  | 121 | typedef struct { | 
|  | 122 | int active; | 
|  | 123 | thread_info_t   data; | 
|  | 124 | pthread_t       thread; | 
|  | 125 | } pthread_info_t; | 
|  | 126 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 127 | static thread_info_t    base_info; | 
|  | 128 | static pthread_info_t   threads[MAX_NUM_THREADS]; | 
|  | 129 |  | 
|  | 130 | static void *handle_ssl_connection( void *data ) | 
|  | 131 | { | 
|  | 132 | int ret, len; | 
|  | 133 | thread_info_t *thread_info = (thread_info_t *) data; | 
|  | 134 | int client_fd = thread_info->client_fd; | 
|  | 135 | int thread_id = (int) pthread_self(); | 
|  | 136 | unsigned char buf[1024]; | 
|  | 137 | char pers[50]; | 
|  | 138 | ssl_context ssl; | 
|  | 139 | ctr_drbg_context ctr_drbg; | 
|  | 140 |  | 
| Manuel Pégourié-Gonnard | 955028f | 2014-07-12 01:27:34 +0200 | [diff] [blame] | 141 | /* Make sure memory references are valid */ | 
|  | 142 | memset( &ssl, 0, sizeof( ssl_context ) ); | 
|  | 143 | memset( &ctr_drbg, 0, sizeof( ctr_drbg_context ) ); | 
|  | 144 |  | 
| Rich Evans | 783d9d1 | 2015-01-30 11:11:57 +0000 | [diff] [blame] | 145 | polarssl_snprintf( pers, sizeof(pers), "SSL Pthread Thread %d", thread_id ); | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 146 | polarssl_printf( "  [ #%d ]  Client FD %d\n", thread_id, client_fd ); | 
|  | 147 | polarssl_printf( "  [ #%d ]  Seeding the random number generator...\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 148 |  | 
|  | 149 | /* entropy_func() is thread-safe if POLARSSL_THREADING_C is set | 
|  | 150 | */ | 
|  | 151 | if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, thread_info->entropy, | 
|  | 152 | (const unsigned char *) pers, | 
|  | 153 | strlen( pers ) ) ) != 0 ) | 
|  | 154 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 155 | polarssl_printf( "  [ #%d ]  failed: ctr_drbg_init returned -0x%04x\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 156 | thread_id, -ret ); | 
|  | 157 | goto thread_exit; | 
|  | 158 | } | 
|  | 159 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 160 | polarssl_printf( "  [ #%d ]  ok\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 161 |  | 
|  | 162 | /* | 
|  | 163 | * 4. Setup stuff | 
|  | 164 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 165 | polarssl_printf( "  [ #%d ]  Setting up the SSL data....\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 166 |  | 
|  | 167 | if( ( ret = ssl_init( &ssl ) ) != 0 ) | 
|  | 168 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 169 | polarssl_printf( "  [ #%d ]  failed: ssl_init returned -0x%04x\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 170 | thread_id, -ret ); | 
|  | 171 | goto thread_exit; | 
|  | 172 | } | 
|  | 173 |  | 
|  | 174 | ssl_set_endpoint( &ssl, SSL_IS_SERVER ); | 
|  | 175 | ssl_set_authmode( &ssl, SSL_VERIFY_NONE ); | 
|  | 176 |  | 
| Manuel Pégourié-Gonnard | 448ea50 | 2015-01-12 11:40:14 +0100 | [diff] [blame] | 177 | /* SSLv3 is deprecated, set minimum to TLS 1.0 */ | 
|  | 178 | ssl_set_min_version( &ssl, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1 ); | 
| Manuel Pégourié-Gonnard | fa06581 | 2015-01-12 14:05:33 +0100 | [diff] [blame] | 179 | /* RC4 is deprecated, disable it */ | 
|  | 180 | ssl_set_arc4_support( &ssl, SSL_ARC4_DISABLED ); | 
| Manuel Pégourié-Gonnard | 448ea50 | 2015-01-12 11:40:14 +0100 | [diff] [blame] | 181 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 182 | ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg ); | 
|  | 183 | ssl_set_dbg( &ssl, my_mutexed_debug, stdout ); | 
|  | 184 |  | 
|  | 185 | /* ssl_cache_get() and ssl_cache_set() are thread-safe if | 
|  | 186 | * POLARSSL_THREADING_C is set. | 
|  | 187 | */ | 
|  | 188 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 189 | ssl_set_session_cache( &ssl, ssl_cache_get, thread_info->cache, | 
|  | 190 | ssl_cache_set, thread_info->cache ); | 
|  | 191 | #endif | 
|  | 192 |  | 
|  | 193 | ssl_set_ca_chain( &ssl, thread_info->ca_chain, NULL, NULL ); | 
| Manuel Pégourié-Gonnard | c5fd391 | 2014-07-08 14:05:52 +0200 | [diff] [blame] | 194 | if( ( ret = ssl_set_own_cert( &ssl, thread_info->server_cert, thread_info->server_key ) ) != 0 ) | 
|  | 195 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 196 | polarssl_printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret ); | 
| Manuel Pégourié-Gonnard | 955028f | 2014-07-12 01:27:34 +0200 | [diff] [blame] | 197 | goto thread_exit; | 
| Manuel Pégourié-Gonnard | c5fd391 | 2014-07-08 14:05:52 +0200 | [diff] [blame] | 198 | } | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 199 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 200 | polarssl_printf( "  [ #%d ]  ok\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 201 |  | 
|  | 202 | ssl_set_bio( &ssl, net_recv, &client_fd, | 
|  | 203 | net_send, &client_fd ); | 
|  | 204 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 205 | polarssl_printf( "  [ #%d ]  ok\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 206 |  | 
|  | 207 | /* | 
|  | 208 | * 5. Handshake | 
|  | 209 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 210 | polarssl_printf( "  [ #%d ]  Performing the SSL/TLS handshake\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 211 |  | 
|  | 212 | while( ( ret = ssl_handshake( &ssl ) ) != 0 ) | 
|  | 213 | { | 
|  | 214 | if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) | 
|  | 215 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 216 | polarssl_printf( "  [ #%d ]  failed: ssl_handshake returned -0x%04x\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 217 | thread_id, -ret ); | 
|  | 218 | goto thread_exit; | 
|  | 219 | } | 
|  | 220 | } | 
|  | 221 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 222 | polarssl_printf( "  [ #%d ]  ok\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 223 |  | 
|  | 224 | /* | 
|  | 225 | * 6. Read the HTTP Request | 
|  | 226 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 227 | polarssl_printf( "  [ #%d ]  < Read from client\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 228 |  | 
|  | 229 | do | 
|  | 230 | { | 
|  | 231 | len = sizeof( buf ) - 1; | 
|  | 232 | memset( buf, 0, sizeof( buf ) ); | 
|  | 233 | ret = ssl_read( &ssl, buf, len ); | 
|  | 234 |  | 
|  | 235 | if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE ) | 
|  | 236 | continue; | 
|  | 237 |  | 
|  | 238 | if( ret <= 0 ) | 
|  | 239 | { | 
|  | 240 | switch( ret ) | 
|  | 241 | { | 
|  | 242 | case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY: | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 243 | polarssl_printf( "  [ #%d ]  connection was closed gracefully\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 244 | thread_id ); | 
|  | 245 | goto thread_exit; | 
|  | 246 |  | 
|  | 247 | case POLARSSL_ERR_NET_CONN_RESET: | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 248 | polarssl_printf( "  [ #%d ]  connection was reset by peer\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 249 | thread_id ); | 
|  | 250 | goto thread_exit; | 
|  | 251 |  | 
|  | 252 | default: | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 253 | polarssl_printf( "  [ #%d ]  ssl_read returned -0x%04x\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 254 | thread_id, -ret ); | 
|  | 255 | goto thread_exit; | 
|  | 256 | } | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 257 | } | 
|  | 258 |  | 
|  | 259 | len = ret; | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 260 | polarssl_printf( "  [ #%d ]  %d bytes read\n=====\n%s\n=====\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 261 | thread_id, len, (char *) buf ); | 
|  | 262 |  | 
|  | 263 | if( ret > 0 ) | 
|  | 264 | break; | 
|  | 265 | } | 
|  | 266 | while( 1 ); | 
|  | 267 |  | 
|  | 268 | /* | 
|  | 269 | * 7. Write the 200 Response | 
|  | 270 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 271 | polarssl_printf( "  [ #%d ]  > Write to client:\n", thread_id ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 272 |  | 
|  | 273 | len = sprintf( (char *) buf, HTTP_RESPONSE, | 
|  | 274 | ssl_get_ciphersuite( &ssl ) ); | 
|  | 275 |  | 
|  | 276 | while( ( ret = ssl_write( &ssl, buf, len ) ) <= 0 ) | 
|  | 277 | { | 
|  | 278 | if( ret == POLARSSL_ERR_NET_CONN_RESET ) | 
|  | 279 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 280 | polarssl_printf( "  [ #%d ]  failed: peer closed the connection\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 281 | thread_id ); | 
|  | 282 | goto thread_exit; | 
|  | 283 | } | 
|  | 284 |  | 
|  | 285 | if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) | 
|  | 286 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 287 | polarssl_printf( "  [ #%d ]  failed: ssl_write returned -0x%04x\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 288 | thread_id, ret ); | 
|  | 289 | goto thread_exit; | 
|  | 290 | } | 
|  | 291 | } | 
|  | 292 |  | 
|  | 293 | len = ret; | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 294 | polarssl_printf( "  [ #%d ]  %d bytes written\n=====\n%s\n=====\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 295 | thread_id, len, (char *) buf ); | 
|  | 296 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 297 | polarssl_printf( "  [ #%d ]  . Closing the connection...", thread_id ); | 
| Manuel Pégourié-Gonnard | 6b0d268 | 2014-03-25 11:24:43 +0100 | [diff] [blame] | 298 |  | 
|  | 299 | while( ( ret = ssl_close_notify( &ssl ) ) < 0 ) | 
|  | 300 | { | 
|  | 301 | if( ret != POLARSSL_ERR_NET_WANT_READ && | 
|  | 302 | ret != POLARSSL_ERR_NET_WANT_WRITE ) | 
|  | 303 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 304 | polarssl_printf( "  [ #%d ]  failed: ssl_close_notify returned -0x%04x\n", | 
| Manuel Pégourié-Gonnard | 6b0d268 | 2014-03-25 11:24:43 +0100 | [diff] [blame] | 305 | thread_id, ret ); | 
|  | 306 | goto thread_exit; | 
|  | 307 | } | 
|  | 308 | } | 
|  | 309 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 310 | polarssl_printf( " ok\n" ); | 
| Manuel Pégourié-Gonnard | 6b0d268 | 2014-03-25 11:24:43 +0100 | [diff] [blame] | 311 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 312 | ret = 0; | 
|  | 313 |  | 
|  | 314 | thread_exit: | 
|  | 315 |  | 
|  | 316 | #ifdef POLARSSL_ERROR_C | 
|  | 317 | if( ret != 0 ) | 
|  | 318 | { | 
|  | 319 | char error_buf[100]; | 
|  | 320 | polarssl_strerror( ret, error_buf, 100 ); | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 321 | polarssl_printf("  [ #%d ]  Last error was: -0x%04x - %s\n\n", | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 322 | thread_id, -ret, error_buf ); | 
|  | 323 | } | 
|  | 324 | #endif | 
|  | 325 |  | 
|  | 326 | net_close( client_fd ); | 
| Manuel Pégourié-Gonnard | 955028f | 2014-07-12 01:27:34 +0200 | [diff] [blame] | 327 | ctr_drbg_free( &ctr_drbg ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 328 | ssl_free( &ssl ); | 
|  | 329 |  | 
|  | 330 | thread_info->thread_complete = 1; | 
|  | 331 |  | 
|  | 332 | return( NULL ); | 
|  | 333 | } | 
|  | 334 |  | 
|  | 335 | static int thread_create( int client_fd ) | 
|  | 336 | { | 
|  | 337 | int ret, i; | 
|  | 338 |  | 
|  | 339 | /* | 
|  | 340 | * Find in-active or finished thread slot | 
|  | 341 | */ | 
|  | 342 | for( i = 0; i < MAX_NUM_THREADS; i++ ) | 
|  | 343 | { | 
|  | 344 | if( threads[i].active == 0 ) | 
|  | 345 | break; | 
|  | 346 |  | 
|  | 347 | if( threads[i].data.thread_complete == 1 ) | 
|  | 348 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 349 | polarssl_printf( "  [ main ]  Cleaning up thread %d\n", i ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 350 | pthread_join(threads[i].thread, NULL ); | 
|  | 351 | memset( &threads[i], 0, sizeof(pthread_info_t) ); | 
|  | 352 | break; | 
|  | 353 | } | 
|  | 354 | } | 
|  | 355 |  | 
|  | 356 | if( i == MAX_NUM_THREADS ) | 
|  | 357 | return( -1 ); | 
|  | 358 |  | 
|  | 359 | /* | 
|  | 360 | * Fill thread-info for thread | 
|  | 361 | */ | 
|  | 362 | memcpy( &threads[i].data, &base_info, sizeof(base_info) ); | 
|  | 363 | threads[i].active = 1; | 
|  | 364 | threads[i].data.client_fd = client_fd; | 
|  | 365 |  | 
|  | 366 | if( ( ret = pthread_create( &threads[i].thread, NULL, handle_ssl_connection,                                &threads[i].data ) ) != 0 ) | 
|  | 367 | { | 
|  | 368 | return( ret ); | 
|  | 369 | } | 
|  | 370 |  | 
|  | 371 | return( 0 ); | 
|  | 372 | } | 
|  | 373 |  | 
| Rich Evans | 85b05ec | 2015-02-12 11:37:29 +0000 | [diff] [blame] | 374 | int main( void ) | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 375 | { | 
|  | 376 | int ret; | 
|  | 377 | int listen_fd; | 
|  | 378 | int client_fd = -1; | 
|  | 379 |  | 
|  | 380 | entropy_context entropy; | 
|  | 381 | x509_crt srvcert; | 
|  | 382 | pk_context pkey; | 
|  | 383 | #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) | 
|  | 384 | unsigned char alloc_buf[100000]; | 
|  | 385 | #endif | 
|  | 386 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 387 | ssl_cache_context cache; | 
|  | 388 | #endif | 
|  | 389 |  | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 390 | #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) | 
|  | 391 | memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) ); | 
|  | 392 | #endif | 
|  | 393 |  | 
|  | 394 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 395 | ssl_cache_init( &cache ); | 
|  | 396 | base_info.cache = &cache; | 
|  | 397 | #endif | 
|  | 398 |  | 
|  | 399 | memset( threads, 0, sizeof(threads) ); | 
|  | 400 |  | 
|  | 401 | polarssl_mutex_init( &debug_mutex ); | 
|  | 402 |  | 
|  | 403 | /* | 
|  | 404 | * We use only a single entropy source that is used in all the threads. | 
|  | 405 | */ | 
|  | 406 | entropy_init( &entropy ); | 
|  | 407 | base_info.entropy = &entropy; | 
|  | 408 |  | 
|  | 409 | /* | 
|  | 410 | * 1. Load the certificates and private RSA key | 
|  | 411 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 412 | polarssl_printf( "\n  . Loading the server cert. and key..." ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 413 | fflush( stdout ); | 
|  | 414 |  | 
|  | 415 | x509_crt_init( &srvcert ); | 
|  | 416 |  | 
|  | 417 | /* | 
|  | 418 | * This demonstration program uses embedded test certificates. | 
|  | 419 | * Instead, you may want to use x509_crt_parse_file() to read the | 
|  | 420 | * server and CA certificates, as well as pk_parse_keyfile(). | 
|  | 421 | */ | 
|  | 422 | ret = x509_crt_parse( &srvcert, (const unsigned char *) test_srv_crt, | 
|  | 423 | strlen( test_srv_crt ) ); | 
|  | 424 | if( ret != 0 ) | 
|  | 425 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 426 | polarssl_printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 427 | goto exit; | 
|  | 428 | } | 
|  | 429 |  | 
|  | 430 | ret = x509_crt_parse( &srvcert, (const unsigned char *) test_ca_list, | 
|  | 431 | strlen( test_ca_list ) ); | 
|  | 432 | if( ret != 0 ) | 
|  | 433 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 434 | polarssl_printf( " failed\n  !  x509_crt_parse returned %d\n\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 435 | goto exit; | 
|  | 436 | } | 
|  | 437 |  | 
|  | 438 | pk_init( &pkey ); | 
|  | 439 | ret =  pk_parse_key( &pkey, (const unsigned char *) test_srv_key, | 
|  | 440 | strlen( test_srv_key ), NULL, 0 ); | 
|  | 441 | if( ret != 0 ) | 
|  | 442 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 443 | polarssl_printf( " failed\n  !  pk_parse_key returned %d\n\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 444 | goto exit; | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | base_info.ca_chain = srvcert.next; | 
|  | 448 | base_info.server_cert = &srvcert; | 
|  | 449 | base_info.server_key = &pkey; | 
|  | 450 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 451 | polarssl_printf( " ok\n" ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 452 |  | 
|  | 453 | /* | 
|  | 454 | * 2. Setup the listening TCP socket | 
|  | 455 | */ | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 456 | polarssl_printf( "  . Bind on https://localhost:4433/ ..." ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 457 | fflush( stdout ); | 
|  | 458 |  | 
|  | 459 | if( ( ret = net_bind( &listen_fd, NULL, 4433 ) ) != 0 ) | 
|  | 460 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 461 | polarssl_printf( " failed\n  ! net_bind returned %d\n\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 462 | goto exit; | 
|  | 463 | } | 
|  | 464 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 465 | polarssl_printf( " ok\n" ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 466 |  | 
|  | 467 | reset: | 
|  | 468 | #ifdef POLARSSL_ERROR_C | 
|  | 469 | if( ret != 0 ) | 
|  | 470 | { | 
|  | 471 | char error_buf[100]; | 
|  | 472 | polarssl_strerror( ret, error_buf, 100 ); | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 473 | polarssl_printf( "  [ main ]  Last error was: -0x%04x - %s\n", -ret, error_buf ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 474 | } | 
|  | 475 | #endif | 
|  | 476 |  | 
|  | 477 | /* | 
|  | 478 | * 3. Wait until a client connects | 
|  | 479 | */ | 
|  | 480 | client_fd = -1; | 
|  | 481 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 482 | polarssl_printf( "  [ main ]  Waiting for a remote connection\n" ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 483 |  | 
|  | 484 | if( ( ret = net_accept( listen_fd, &client_fd, NULL ) ) != 0 ) | 
|  | 485 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 486 | polarssl_printf( "  [ main ] failed: net_accept returned -0x%04x\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 487 | goto exit; | 
|  | 488 | } | 
|  | 489 |  | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 490 | polarssl_printf( "  [ main ]  ok\n" ); | 
|  | 491 | polarssl_printf( "  [ main ]  Creating a new thread\n" ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 492 |  | 
|  | 493 | if( ( ret = thread_create( client_fd ) ) != 0 ) | 
|  | 494 | { | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 495 | polarssl_printf( "  [ main ]  failed: thread_create returned %d\n", ret ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 496 | net_close( client_fd ); | 
|  | 497 | goto reset; | 
|  | 498 | } | 
|  | 499 |  | 
|  | 500 | ret = 0; | 
|  | 501 | goto reset; | 
|  | 502 |  | 
|  | 503 | exit: | 
|  | 504 | x509_crt_free( &srvcert ); | 
|  | 505 | pk_free( &pkey ); | 
|  | 506 | #if defined(POLARSSL_SSL_CACHE_C) | 
|  | 507 | ssl_cache_free( &cache ); | 
|  | 508 | #endif | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 509 | entropy_free( &entropy ); | 
|  | 510 |  | 
|  | 511 | polarssl_mutex_free( &debug_mutex ); | 
|  | 512 |  | 
|  | 513 | #if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) | 
|  | 514 | memory_buffer_alloc_free(); | 
|  | 515 | #endif | 
|  | 516 |  | 
|  | 517 | #if defined(_WIN32) | 
| Rich Evans | f90016a | 2015-01-19 14:26:37 +0000 | [diff] [blame] | 518 | polarssl_printf( "  Press Enter to exit this program.\n" ); | 
| Paul Bakker | f9c4953 | 2013-12-19 15:40:58 +0100 | [diff] [blame] | 519 | fflush( stdout ); getchar(); | 
|  | 520 | #endif | 
|  | 521 |  | 
|  | 522 | return( ret ); | 
|  | 523 | } | 
|  | 524 |  | 
|  | 525 | #endif /* POLARSSL_BIGNUM_C && POLARSSL_CERTS_C && POLARSSL_ENTROPY_C && | 
|  | 526 | POLARSSL_SSL_TLS_C && POLARSSL_SSL_SRV_C && POLARSSL_NET_C && | 
|  | 527 | POLARSSL_RSA_C && POLARSSL_CTR_DRBG_C && POLARSSL_THREADING_C && | 
|  | 528 | POLARSSL_THREADING_PTHREAD */ |