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