Rev 9082 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8774 | rgimad | 1 | /* |
2 | * SSL client demonstration program |
||
3 | * |
||
4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved |
||
5 | * SPDX-License-Identifier: GPL-2.0 |
||
6 | * |
||
7 | * This program is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * This program is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License along |
||
18 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
||
20 | * |
||
21 | * This file is part of mbed TLS (https://tls.mbed.org) |
||
22 | */ |
||
9661 | turbocat | 23 | /*#if !defined(MBEDTLS_CONFIG_FILE) |
8774 | rgimad | 24 | #include "mbedtls/config.h" |
25 | #else |
||
26 | #include MBEDTLS_CONFIG_FILE |
||
9661 | turbocat | 27 | #endif*/ |
8774 | rgimad | 28 | |
9076 | turbocat | 29 | #include |
30 | |||
31 | //#if defined(MBEDTLS_PLATFORM_C) |
||
32 | //#include "mbedtls/platform.h" |
||
33 | //#else |
||
8774 | rgimad | 34 | #include |
35 | #include |
||
36 | #define mbedtls_time time |
||
37 | #define mbedtls_time_t time_t |
||
38 | #define mbedtls_fprintf fprintf |
||
39 | #define mbedtls_printf printf |
||
40 | #define mbedtls_exit exit |
||
9076 | turbocat | 41 | #define MBEDTLS_EXIT_SUCCESS 0 |
42 | #define MBEDTLS_EXIT_FAILURE -1 |
||
43 | //#endif /* MBEDTLS_PLATFORM_C */ |
||
8774 | rgimad | 44 | |
9076 | turbocat | 45 | //#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \ |
8774 | rgimad | 46 | !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \ |
47 | !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \ |
||
48 | !defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \ |
||
49 | !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) |
||
9076 | turbocat | 50 | /*int main( void ) |
8774 | rgimad | 51 | { |
52 | mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or " |
||
53 | "MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or " |
||
54 | "MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or " |
||
55 | "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C " |
||
56 | "not defined.\n"); |
||
57 | return( 0 ); |
||
58 | } |
||
9076 | turbocat | 59 | //#else*/ |
8774 | rgimad | 60 | |
61 | #include "mbedtls/net_sockets.h" |
||
62 | #include "mbedtls/debug.h" |
||
63 | #include "mbedtls/ssl.h" |
||
64 | #include "mbedtls/entropy.h" |
||
65 | #include "mbedtls/ctr_drbg.h" |
||
66 | #include "mbedtls/error.h" |
||
67 | #include "mbedtls/certs.h" |
||
68 | |||
69 | #include |
||
70 | |||
9082 | turbocat | 71 | #define SERVER_NAME_SIZE 255 |
72 | #define SERVER_PORT_SIZE 16 |
||
73 | #define REQUEST_URL_SIZE STDIO_MAX_MEM-SERVER_NAME_SIZE-32 |
||
8774 | rgimad | 74 | |
9082 | turbocat | 75 | static char server_port[SERVER_PORT_SIZE]; |
76 | static char server_name[SERVER_NAME_SIZE]; |
||
77 | static char request_url[REQUEST_URL_SIZE]; |
||
78 | static char get_request[STDIO_MAX_MEM]; |
||
79 | |||
8774 | rgimad | 80 | #define DEBUG_LEVEL 1 |
81 | |||
9076 | turbocat | 82 | extern int *_mbedtls_test_cas_pem_len; |
83 | extern char* _mbedtls_test_cas_pem; |
||
8774 | rgimad | 84 | |
9076 | turbocat | 85 | #define mbedtls_test_cas_pem_len *_mbedtls_test_cas_pem_len |
86 | #define mbedtls_test_cas_pem _mbedtls_test_cas_pem |
||
87 | |||
88 | //gmtime(time_t t){puts("gmtime stub");}; |
||
89 | |||
90 | //int load_network_obj(){return networklib_init();} |
||
91 | |||
8774 | rgimad | 92 | static void my_debug( void *ctx, int level, |
93 | const char *file, int line, |
||
94 | const char *str ) |
||
95 | { |
||
96 | ((void) level); |
||
97 | |||
98 | //mbedtls_fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str ); |
||
99 | //fflush( (FILE *) ctx ); |
||
100 | printf("%s:%04d: %s", file, line, str ); |
||
101 | } |
||
102 | |||
9082 | turbocat | 103 | char* safe_gets(char *str, size_t n){ |
104 | char* ret = fgets(str, n, stdin); |
||
105 | if(ret){ |
||
106 | size_t str_len = strlen(str); |
||
107 | if(str[str_len-1]=='\n'){ |
||
108 | str[str_len-1]= '\0'; |
||
109 | } |
||
110 | return str; |
||
111 | } |
||
112 | return NULL; |
||
113 | } |
||
114 | |||
115 | extern int mbedtls_load(); |
||
116 | extern int mbedtls_init(); |
||
117 | |||
8774 | rgimad | 118 | int main( void ) |
119 | { |
||
9076 | turbocat | 120 | if(mbedtls_load()){ |
121 | printf("mbedtls.obj not load!\n"); |
||
122 | return -1; |
||
123 | } |
||
124 | if(mbedtls_init()){ |
||
125 | puts("mbedtls.obj not init!"); |
||
126 | return -1; |
||
127 | } |
||
128 | |||
9082 | turbocat | 129 | puts("Enter server name : "); |
130 | safe_gets(server_name, SERVER_NAME_SIZE); |
||
8774 | rgimad | 131 | |
9082 | turbocat | 132 | puts("Enter request_url : "); |
133 | safe_gets(request_url, REQUEST_URL_SIZE); |
||
134 | |||
135 | puts("Enter server port : "); |
||
136 | safe_gets(server_port, SERVER_PORT_SIZE); |
||
137 | |||
138 | sprintf(get_request, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", request_url, server_name); |
||
139 | //puts(get_request); |
||
8774 | rgimad | 140 | int ret = 1, len; |
141 | int exit_code = MBEDTLS_EXIT_FAILURE; |
||
142 | mbedtls_net_context server_fd; |
||
143 | uint32_t flags; |
||
9082 | turbocat | 144 | unsigned char buf[STDIO_MAX_MEM]; |
8774 | rgimad | 145 | const char *pers = "ssl_client1"; |
146 | mbedtls_entropy_context entropy; |
||
147 | mbedtls_ctr_drbg_context ctr_drbg; |
||
148 | mbedtls_ssl_context ssl; |
||
149 | mbedtls_ssl_config conf; |
||
150 | mbedtls_x509_crt cacert; |
||
151 | |||
152 | #if defined(MBEDTLS_DEBUG_C) |
||
9076 | turbocat | 153 | // mbedtls_debug_set_threshold( DEBUG_LEVEL ); |
8774 | rgimad | 154 | #endif |
155 | |||
156 | /* |
||
157 | * 0. Initialize the RNG and the session data |
||
158 | */ |
||
159 | mbedtls_net_init( &server_fd ); |
||
160 | mbedtls_ssl_init( &ssl ); |
||
161 | mbedtls_ssl_config_init( &conf ); |
||
162 | mbedtls_x509_crt_init( &cacert ); |
||
163 | mbedtls_ctr_drbg_init( &ctr_drbg ); |
||
164 | mbedtls_printf( "\n . Seeding the random number generator..." ); |
||
165 | //fflush( stdout ); |
||
166 | mbedtls_entropy_init( &entropy ); |
||
167 | if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, |
||
168 | (const unsigned char *) pers, |
||
169 | strlen( pers ) ) ) != 0 ) |
||
170 | { |
||
171 | mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); |
||
172 | goto exit; |
||
173 | } |
||
9076 | turbocat | 174 | |
8774 | rgimad | 175 | mbedtls_printf( " ok\n" ); |
9076 | turbocat | 176 | |
8774 | rgimad | 177 | /* |
178 | * 0. Initialize certificates |
||
9076 | turbocat | 179 | */; |
8774 | rgimad | 180 | mbedtls_printf( " . Loading the CA root certificate ..." ); |
181 | //fflush( stdout ); |
||
9076 | turbocat | 182 | |
8774 | rgimad | 183 | ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem, |
184 | mbedtls_test_cas_pem_len ); |
||
185 | if( ret < 0 ) |
||
186 | { |
||
187 | mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret ); |
||
188 | goto exit; |
||
189 | } |
||
190 | |||
191 | mbedtls_printf( " ok (%d skipped)\n", ret ); |
||
9076 | turbocat | 192 | |
8774 | rgimad | 193 | /* |
194 | * 1. Start the connection |
||
195 | */ |
||
9082 | turbocat | 196 | mbedtls_printf( " . Connecting to tcp/%s/%s...", server_name, server_port ); |
8774 | rgimad | 197 | //fflush( stdout ); |
198 | |||
9082 | turbocat | 199 | if( ( ret = mbedtls_net_connect( &server_fd, server_name, |
200 | server_port, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) |
||
8774 | rgimad | 201 | { |
202 | mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); |
||
203 | goto exit; |
||
204 | } |
||
205 | |||
206 | mbedtls_printf( " ok\n" ); |
||
207 | |||
208 | /* |
||
209 | * 2. Setup stuff |
||
210 | */ |
||
211 | mbedtls_printf( " . Setting up the SSL/TLS structure..." ); |
||
212 | //fflush( stdout ); |
||
213 | |||
214 | if( ( ret = mbedtls_ssl_config_defaults( &conf, |
||
215 | MBEDTLS_SSL_IS_CLIENT, |
||
216 | MBEDTLS_SSL_TRANSPORT_STREAM, |
||
217 | MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 ) |
||
218 | { |
||
219 | mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ); |
||
220 | goto exit; |
||
221 | } |
||
222 | |||
223 | mbedtls_printf( " ok\n" ); |
||
224 | |||
225 | /* OPTIONAL is not optimal for security, |
||
226 | * but makes interop easier in this simplified example */ |
||
227 | mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL ); |
||
228 | mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); |
||
229 | mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); |
||
230 | mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); |
||
231 | |||
232 | if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 ) |
||
233 | { |
||
234 | mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret ); |
||
235 | goto exit; |
||
236 | } |
||
237 | |||
9082 | turbocat | 238 | if( ( ret = mbedtls_ssl_set_hostname( &ssl, server_name ) ) != 0 ) |
8774 | rgimad | 239 | { |
240 | mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ); |
||
241 | goto exit; |
||
242 | } |
||
243 | |||
244 | mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL ); |
||
245 | /* |
||
246 | * 4. Handshake |
||
247 | */ |
||
248 | mbedtls_printf( " . Performing the SSL/TLS handshake..." ); |
||
249 | //fflush( stdout ); |
||
250 | |||
251 | while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 ) |
||
252 | { |
||
253 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) |
||
254 | { |
||
255 | mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); |
||
256 | goto exit; |
||
257 | } |
||
258 | } |
||
259 | |||
260 | mbedtls_printf( " ok\n" ); |
||
261 | |||
262 | /* |
||
263 | * 5. Verify the server certificate |
||
264 | */ |
||
265 | mbedtls_printf( " . Verifying peer X.509 certificate..." ); |
||
266 | |||
267 | /* In real life, we probably want to bail out when ret != 0 */ |
||
268 | if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 ) |
||
269 | { |
||
270 | char vrfy_buf[512]; |
||
271 | |||
272 | mbedtls_printf( " failed\n" ); |
||
273 | |||
274 | mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); |
||
275 | |||
276 | mbedtls_printf( "%s\n", vrfy_buf ); |
||
277 | } |
||
278 | else |
||
279 | mbedtls_printf( " ok\n" ); |
||
280 | |||
281 | /* |
||
282 | * 3. Write the GET request |
||
283 | */ |
||
284 | mbedtls_printf( " > Write to server:" ); |
||
285 | //fflush( stdout ); |
||
286 | |||
9082 | turbocat | 287 | len = sprintf( (char *) buf, get_request ); |
8774 | rgimad | 288 | |
289 | while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 ) |
||
290 | { |
||
291 | if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) |
||
292 | { |
||
293 | mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret ); |
||
294 | goto exit; |
||
295 | } |
||
296 | } |
||
297 | |||
298 | len = ret; |
||
299 | mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf ); |
||
300 | |||
301 | /* |
||
302 | * 7. Read the HTTP response |
||
303 | */ |
||
304 | mbedtls_printf( " < Read from server:" ); |
||
305 | //fflush( stdout ); |
||
306 | |||
307 | do |
||
308 | { |
||
309 | len = sizeof( buf ) - 1; |
||
310 | memset( buf, 0, sizeof( buf ) ); |
||
311 | ret = mbedtls_ssl_read( &ssl, buf, len ); |
||
312 | |||
313 | if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) |
||
314 | continue; |
||
315 | |||
316 | if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ) |
||
317 | break; |
||
318 | |||
319 | if( ret < 0 ) |
||
320 | { |
||
321 | mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret ); |
||
322 | break; |
||
323 | } |
||
324 | |||
325 | if( ret == 0 ) |
||
326 | { |
||
327 | mbedtls_printf( "\n\nEOF\n\n" ); |
||
328 | break; |
||
329 | } |
||
330 | |||
331 | len = ret; |
||
332 | mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf ); |
||
333 | } |
||
334 | while( 1 ); |
||
335 | |||
336 | mbedtls_ssl_close_notify( &ssl ); |
||
337 | |||
338 | exit_code = MBEDTLS_EXIT_SUCCESS; |
||
339 | |||
340 | exit: |
||
9076 | turbocat | 341 | //#ifdef MBEDTLS_ERROR_C |
8774 | rgimad | 342 | if( exit_code != MBEDTLS_EXIT_SUCCESS ) |
343 | { |
||
9076 | turbocat | 344 | static char error_buf[100]; |
8774 | rgimad | 345 | mbedtls_strerror( ret, error_buf, 100 ); |
346 | mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf ); |
||
347 | } |
||
9076 | turbocat | 348 | //#endif |
8774 | rgimad | 349 | |
350 | mbedtls_net_free( &server_fd ); |
||
351 | |||
352 | mbedtls_x509_crt_free( &cacert ); |
||
353 | mbedtls_ssl_free( &ssl ); |
||
354 | mbedtls_ssl_config_free( &conf ); |
||
355 | mbedtls_ctr_drbg_free( &ctr_drbg ); |
||
356 | mbedtls_entropy_free( &entropy ); |
||
357 | |||
358 | |||
359 | return( exit_code ); |
||
360 | } |
||
9076 | turbocat | 361 | /*#endif MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C && |
8774 | rgimad | 362 | MBEDTLS_SSL_CLI_C && MBEDTLS_NET_C && MBEDTLS_RSA_C && |
363 | MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C && MBEDTLS_CTR_DRBG_C && |
||
364 | MBEDTLS_X509_CRT_PARSE_C */>>=>> |