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