1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
101
102
103
104
105
106
107
108
109
110
111
112
113
114
120
121
122
123
126
127
128
129
130
135
136
137
138
141
142
143
149
150
151
152
155
156
157
158
159
160
161
162
163
164
165
166
167
168
170
171
172
173
174
179
180
185
186
187
188
191
192
193
201
202
203
204
207
208
209
210
211
212
213
214
215
216
217
221
222
225
226
227
228
229
230
231
239
240
241
242
243
246
247
248
249
250
251
252
253
254
258
259
263
264
269
270
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
296
300
301
302
/* ... */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_time time
#define mbedtls_time_t time_t
#define mbedtls_fprintf fprintf
#define mbedtls_printf printf
/* ... */#endif
#if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_ENTROPY_C) || \
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
!defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
#endif
#if 0
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
"not defined.\n");
return( 0 );
}main (void) { ... }
/* ... */#else
#include "mbedtls/net_sockets.h"
#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/error.h"
#include "mbedtls/certs.h"
#include "mbedtls/memory_buffer_alloc.h"
#include "main.h"
#include "cmsis_os.h"
#include <string.h>
11 includes
static mbedtls_net_context server_fd;
static uint32_t flags;
static uint8_t buf[1024];
static const uint8_t *pers = (uint8_t *)("ssl_client");
static uint8_t vrfy_buf[512];
static int ret;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
#ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C
uint8_t memory_buf[MAX_MEM_SIZE];
#endif
void SSL_Client(void const *argument)
{
int len;
/* ... */
#ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C
mbedtls_memory_buffer_alloc_init(memory_buf, sizeof(memory_buf));
#endif
mbedtls_net_init(NULL);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_printf( "\n . Seeding the random number generator..." );
mbedtls_entropy_init( &entropy );
len = strlen((char *)pers);
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
(const unsigned char *) pers, len ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
goto exit;
}if (( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, len ) ) != 0) { ... }
mbedtls_printf( " ok\n" );
/* ... */
mbedtls_printf( " . Loading the CA root certificate ..." );
ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_cas_pem,
mbedtls_test_cas_pem_len );
if( ret < 0 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret );
goto exit;
}if (ret < 0) { ... }
mbedtls_printf( " ok (%d skipped)\n", ret );
/* ... */
mbedtls_printf( " . Connecting to tcp/%s/%s...", SERVER_NAME, SERVER_PORT );
if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME,
SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret );
goto exit;
}if (( ret = mbedtls_net_connect( &server_fd, SERVER_NAME, SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0) { ... }
mbedtls_printf( " ok\n" );
/* ... */
mbedtls_printf( " . Setting up the SSL/TLS structure..." );
if( ( ret = mbedtls_ssl_config_defaults( &conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
goto exit;
}if (( ret = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0) { ... }
mbedtls_printf( " ok\n" );
/* ... */
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned %d\n\n", ret );
goto exit;
}if (( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0) { ... }
if( ( ret = mbedtls_ssl_set_hostname( &ssl, "localhost" ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
goto exit;
}if (( ret = mbedtls_ssl_set_hostname( &ssl, "localhost" ) ) != 0) { ... }
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
/* ... */
mbedtls_printf( " . Performing the SSL/TLS handshake..." );
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
goto exit;
}if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ... }
}while (( ret = mbedtls_ssl_handshake( &ssl ) ) != 0) { ... }
mbedtls_printf( " ok\n" );
/* ... */
mbedtls_printf( " . Verifying peer X.509 certificate..." );
if( ( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0 )
{
mbedtls_printf( " failed\n" );
mbedtls_x509_crt_verify_info( (char *)vrfy_buf, sizeof( vrfy_buf ), " ! ", flags );
mbedtls_printf( "%s\n", vrfy_buf );
}if (( flags = mbedtls_ssl_get_verify_result( &ssl ) ) != 0) { ... }
else
{
mbedtls_printf( " ok\n" );
}else { ... }
/* ... */
mbedtls_printf( " > Write to server:" );
sprintf( (char *) buf, GET_REQUEST );
len = strlen((char *) buf);
while( ( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0 )
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
goto exit;
}if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ... }
}while (( ret = mbedtls_ssl_write( &ssl, buf, len ) ) <= 0) { ... }
len = ret;
mbedtls_printf( " %d bytes written\n\n%s", len, (char *) buf );
/* ... */
mbedtls_printf( " < Read from server:" );
do
{
len = sizeof( buf ) - 1;
memset( buf, 0, sizeof( buf ) );
ret = mbedtls_ssl_read( &ssl, buf, len );
if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
{
continue;
}if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { ... }
if( ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY )
{
break;
}if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { ... }
if( ret < 0 )
{
mbedtls_printf( "failed\n ! mbedtls_ssl_read returned %d\n\n", ret );
break;
}if (ret < 0) { ... }
if( ret == 0 )
{
mbedtls_printf( "\n\nEOF\n\n" );
break;
}if (ret == 0) { ... }
len = ret;
mbedtls_printf( " %d bytes read\n\n%s", len, (char *) buf );
...}
while( 1 );
mbedtls_ssl_close_notify( &ssl );
exit:
mbedtls_net_free( &server_fd );
mbedtls_x509_crt_free( &cacert );
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
if ((ret < 0) && (ret != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY))
{
Error_Handler();
}if ((ret < 0) && (ret != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)) { ... }
else
{
Success_Handler();
}else { ... }
}{ ... }
/* ... */#endif
/* ... */