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