1 /*
2 * Minimal SSL client, used for memory measurements.
3 * (meant to be used with config-suite-b.h or config-ccm-psk-tls1_2.h)
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
6 * SPDX-License-Identifier: GPL-2.0
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * This file is part of mbed TLS (https://tls.mbed.org)
23 */
24
25 #if !defined(MBEDTLS_CONFIG_FILE)
26 #include "mbedtls/config.h"
27 #else
28 #include MBEDTLS_CONFIG_FILE
29 #endif
30
31 /*
32 * We're creating and connecting the socket "manually" rather than using the
33 * NET module, in order to avoid the overhead of getaddrinfo() which tends to
34 * dominate memory usage in small configurations. For the sake of simplicity,
35 * only a Unix version is implemented.
36 *
37 * Warning: we are breaking some of the abtractions from the NET layer here.
38 * This is not a good example for general use. This programs has the specific
39 * goal of minimizing use of the libc functions on full-blown OSes.
40 */
41 #if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
42 #define UNIX
43 #endif
44
45 #if !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_ENTROPY_C) || \
46 !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) || \
47 !defined(UNIX)
48
49 #if defined(MBEDTLS_PLATFORM_C)
50 #include "mbedtls/platform.h"
51 #else
52 #include <stdio.h>
53 #define mbedtls_printf printf
54 #endif
55
main(void)56 int main( void )
57 {
58 mbedtls_printf( "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_ENTROPY_C and/or "
59 "MBEDTLS_NET_C and/or MBEDTLS_SSL_CLI_C and/or UNIX "
60 "not defined.\n");
61 return( 0 );
62 }
63 #else
64
65 #if defined(MBEDTLS_PLATFORM_C)
66 #include "mbedtls/platform.h"
67 #else
68 #include <stdlib.h>
69 #endif
70
71 #include <string.h>
72
73 #include "mbedtls/net_sockets.h"
74 #include "mbedtls/ssl.h"
75 #include "mbedtls/entropy.h"
76 #include "mbedtls/ctr_drbg.h"
77
78 #include <sys/socket.h>
79 #include <netinet/in.h>
80 #include <arpa/inet.h>
81
82 /*
83 * Hardcoded values for server host and port
84 */
85 #define PORT_BE 0x1151 /* 4433 */
86 #define PORT_LE 0x5111
87 #define ADDR_BE 0x7f000001 /* 127.0.0.1 */
88 #define ADDR_LE 0x0100007f
89 #define HOSTNAME "localhost" /* for cert verification if enabled */
90
91 #define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
92
93 const char *pers = "mini_client";
94
95 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
96 const unsigned char psk[] = {
97 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
98 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
99 };
100 const char psk_id[] = "Client_identity";
101 #endif
102
103 #if defined(MBEDTLS_X509_CRT_PARSE_C)
104 /* This is tests/data_files/test-ca2.crt, a CA using EC secp384r1 */
105 const unsigned char ca_cert[] = {
106 0x30, 0x82, 0x02, 0x52, 0x30, 0x82, 0x01, 0xd7, 0xa0, 0x03, 0x02, 0x01,
107 0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8,
108 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
109 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
110 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a,
111 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c,
112 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c,
113 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45,
114 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x39,
115 0x32, 0x34, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x32,
116 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a,
117 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
118 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a,
119 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c,
120 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c,
121 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45,
122 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86,
123 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
124 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f,
125 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e,
126 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95,
127 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95,
128 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a,
129 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2,
130 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47,
131 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66,
132 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x81, 0xa0, 0x30, 0x81, 0x9d, 0x30, 0x1d,
133 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x6d, 0x20,
134 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24,
135 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23,
136 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01,
137 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb,
138 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09,
139 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30,
140 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61,
141 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04,
142 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20,
143 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09,
144 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0c, 0x06,
145 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
146 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03,
147 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xc3, 0xb4, 0x62, 0x73, 0x56,
148 0x28, 0x95, 0x00, 0x7d, 0x78, 0x12, 0x26, 0xd2, 0x71, 0x7b, 0x19, 0xf8,
149 0x8a, 0x98, 0x3e, 0x92, 0xfe, 0x33, 0x9e, 0xe4, 0x79, 0xd2, 0xfe, 0x7a,
150 0xb7, 0x87, 0x74, 0x3c, 0x2b, 0xb8, 0xd7, 0x69, 0x94, 0x0b, 0xa3, 0x67,
151 0x77, 0xb8, 0xb3, 0xbe, 0xd1, 0x36, 0x32, 0x02, 0x31, 0x00, 0xfd, 0x67,
152 0x9c, 0x94, 0x23, 0x67, 0xc0, 0x56, 0xba, 0x4b, 0x33, 0x15, 0x00, 0xc6,
153 0xe3, 0xcc, 0x31, 0x08, 0x2c, 0x9c, 0x8b, 0xda, 0xa9, 0x75, 0x23, 0x2f,
154 0xb8, 0x28, 0xe7, 0xf2, 0x9c, 0x14, 0x3a, 0x40, 0x01, 0x5c, 0xaf, 0x0c,
155 0xb2, 0xcf, 0x74, 0x7f, 0x30, 0x9f, 0x08, 0x43, 0xad, 0x20,
156 };
157 #endif /* MBEDTLS_X509_CRT_PARSE_C */
158
159 enum exit_codes
160 {
161 exit_ok = 0,
162 ctr_drbg_seed_failed,
163 ssl_config_defaults_failed,
164 ssl_setup_failed,
165 hostname_failed,
166 socket_failed,
167 connect_failed,
168 x509_crt_parse_failed,
169 ssl_handshake_failed,
170 ssl_write_failed,
171 };
172
main(void)173 int main( void )
174 {
175 int ret = exit_ok;
176 mbedtls_net_context server_fd;
177 struct sockaddr_in addr;
178 #if defined(MBEDTLS_X509_CRT_PARSE_C)
179 mbedtls_x509_crt ca;
180 #endif
181
182 mbedtls_entropy_context entropy;
183 mbedtls_ctr_drbg_context ctr_drbg;
184 mbedtls_ssl_context ssl;
185 mbedtls_ssl_config conf;
186 mbedtls_ctr_drbg_init( &ctr_drbg );
187
188 /*
189 * 0. Initialize and setup stuff
190 */
191 mbedtls_net_init( &server_fd );
192 mbedtls_ssl_init( &ssl );
193 mbedtls_ssl_config_init( &conf );
194 #if defined(MBEDTLS_X509_CRT_PARSE_C)
195 mbedtls_x509_crt_init( &ca );
196 #endif
197
198 mbedtls_entropy_init( &entropy );
199 if( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
200 (const unsigned char *) pers, strlen( pers ) ) != 0 )
201 {
202 ret = ctr_drbg_seed_failed;
203 goto exit;
204 }
205
206 if( mbedtls_ssl_config_defaults( &conf,
207 MBEDTLS_SSL_IS_CLIENT,
208 MBEDTLS_SSL_TRANSPORT_STREAM,
209 MBEDTLS_SSL_PRESET_DEFAULT ) != 0 )
210 {
211 ret = ssl_config_defaults_failed;
212 goto exit;
213 }
214
215 mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
216
217 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
218 mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
219 (const unsigned char *) psk_id, sizeof( psk_id ) - 1 );
220 #endif
221
222 #if defined(MBEDTLS_X509_CRT_PARSE_C)
223 if( mbedtls_x509_crt_parse_der( &ca, ca_cert, sizeof( ca_cert ) ) != 0 )
224 {
225 ret = x509_crt_parse_failed;
226 goto exit;
227 }
228
229 mbedtls_ssl_conf_ca_chain( &conf, &ca, NULL );
230 mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
231 #endif
232
233 if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
234 {
235 ret = ssl_setup_failed;
236 goto exit;
237 }
238
239 #if defined(MBEDTLS_X509_CRT_PARSE_C)
240 if( mbedtls_ssl_set_hostname( &ssl, HOSTNAME ) != 0 )
241 {
242 ret = hostname_failed;
243 goto exit;
244 }
245 #endif
246
247 /*
248 * 1. Start the connection
249 */
250 memset( &addr, 0, sizeof( addr ) );
251 addr.sin_family = AF_INET;
252
253 ret = 1; /* for endianness detection */
254 addr.sin_port = *((char *) &ret) == ret ? PORT_LE : PORT_BE;
255 addr.sin_addr.s_addr = *((char *) &ret) == ret ? ADDR_LE : ADDR_BE;
256 ret = 0;
257
258 if( ( server_fd.fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
259 {
260 ret = socket_failed;
261 goto exit;
262 }
263
264 if( connect( server_fd.fd,
265 (const struct sockaddr *) &addr, sizeof( addr ) ) < 0 )
266 {
267 ret = connect_failed;
268 goto exit;
269 }
270
271 mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
272
273 if( mbedtls_ssl_handshake( &ssl ) != 0 )
274 {
275 ret = ssl_handshake_failed;
276 goto exit;
277 }
278
279 /*
280 * 2. Write the GET request and close the connection
281 */
282 if( mbedtls_ssl_write( &ssl, (const unsigned char *) GET_REQUEST,
283 sizeof( GET_REQUEST ) - 1 ) <= 0 )
284 {
285 ret = ssl_write_failed;
286 goto exit;
287 }
288
289 mbedtls_ssl_close_notify( &ssl );
290
291 exit:
292 mbedtls_net_free( &server_fd );
293
294 mbedtls_ssl_free( &ssl );
295 mbedtls_ssl_config_free( &conf );
296 mbedtls_ctr_drbg_free( &ctr_drbg );
297 mbedtls_entropy_free( &entropy );
298 #if defined(MBEDTLS_X509_CRT_PARSE_C)
299 mbedtls_x509_crt_free( &ca );
300 #endif
301
302 return( ret );
303 }
304 #endif
305