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