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