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