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