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