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