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
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #include "mbedtls/build_info.h"
22
23 #include "mbedtls/platform.h"
24
25 /*
26 * We're creating and connecting the socket "manually" rather than using the
27 * NET module, in order to avoid the overhead of getaddrinfo() which tends to
28 * dominate memory usage in small configurations. For the sake of simplicity,
29 * only a Unix version is implemented.
30 *
31 * Warning: we are breaking some of the abstractions from the NET layer here.
32 * This is not a good example for general use. This programs has the specific
33 * goal of minimizing use of the libc functions on full-blown OSes.
34 */
35 #if defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__)
36 #define UNIX
37 #endif
38
39 #if !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_ENTROPY_C) || \
40 !defined(MBEDTLS_NET_C) || !defined(MBEDTLS_SSL_CLI_C) || \
41 !defined(UNIX)
42
main(void)43 int main(void)
44 {
45 mbedtls_printf("MBEDTLS_CTR_DRBG_C and/or MBEDTLS_ENTROPY_C and/or "
46 "MBEDTLS_NET_C and/or MBEDTLS_SSL_CLI_C and/or UNIX "
47 "not defined.\n");
48 mbedtls_exit(0);
49 }
50 #else
51
52 #include <string.h>
53
54 #include "mbedtls/net_sockets.h"
55 #include "mbedtls/ssl.h"
56 #include "mbedtls/entropy.h"
57 #include "mbedtls/ctr_drbg.h"
58
59 #include <sys/socket.h>
60 #include <netinet/in.h>
61 #include <arpa/inet.h>
62
63 /*
64 * Hardcoded values for server host and port
65 */
66 #define PORT_BE 0x1151 /* 4433 */
67 #define PORT_LE 0x5111
68 #define ADDR_BE 0x7f000001 /* 127.0.0.1 */
69 #define ADDR_LE 0x0100007f
70 #define HOSTNAME "localhost" /* for cert verification if enabled */
71
72 #define GET_REQUEST "GET / HTTP/1.0\r\n\r\n"
73
74 const char *pers = "mini_client";
75
76 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
77 const unsigned char psk[] = {
78 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
79 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
80 };
81 const char psk_id[] = "Client_identity";
82 #endif
83
84 #if defined(MBEDTLS_X509_CRT_PARSE_C)
85 /* This is tests/data_files/test-ca2.crt, a CA using EC secp384r1 */
86 const unsigned char ca_cert[] = {
87 0x30, 0x82, 0x02, 0x52, 0x30, 0x82, 0x01, 0xd7, 0xa0, 0x03, 0x02, 0x01,
88 0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8,
89 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
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, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x39,
96 0x32, 0x34, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x32,
97 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a,
98 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
99 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a,
100 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c,
101 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c,
102 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45,
103 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86,
104 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22,
105 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f,
106 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e,
107 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95,
108 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95,
109 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a,
110 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2,
111 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47,
112 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66,
113 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x81, 0xa0, 0x30, 0x81, 0x9d, 0x30, 0x1d,
114 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x6d, 0x20,
115 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24,
116 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23,
117 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01,
118 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb,
119 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09,
120 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30,
121 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61,
122 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04,
123 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20,
124 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09,
125 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0c, 0x06,
126 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
127 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03,
128 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xc3, 0xb4, 0x62, 0x73, 0x56,
129 0x28, 0x95, 0x00, 0x7d, 0x78, 0x12, 0x26, 0xd2, 0x71, 0x7b, 0x19, 0xf8,
130 0x8a, 0x98, 0x3e, 0x92, 0xfe, 0x33, 0x9e, 0xe4, 0x79, 0xd2, 0xfe, 0x7a,
131 0xb7, 0x87, 0x74, 0x3c, 0x2b, 0xb8, 0xd7, 0x69, 0x94, 0x0b, 0xa3, 0x67,
132 0x77, 0xb8, 0xb3, 0xbe, 0xd1, 0x36, 0x32, 0x02, 0x31, 0x00, 0xfd, 0x67,
133 0x9c, 0x94, 0x23, 0x67, 0xc0, 0x56, 0xba, 0x4b, 0x33, 0x15, 0x00, 0xc6,
134 0xe3, 0xcc, 0x31, 0x08, 0x2c, 0x9c, 0x8b, 0xda, 0xa9, 0x75, 0x23, 0x2f,
135 0xb8, 0x28, 0xe7, 0xf2, 0x9c, 0x14, 0x3a, 0x40, 0x01, 0x5c, 0xaf, 0x0c,
136 0xb2, 0xcf, 0x74, 0x7f, 0x30, 0x9f, 0x08, 0x43, 0xad, 0x20,
137 };
138 #endif /* MBEDTLS_X509_CRT_PARSE_C */
139
140 enum exit_codes {
141 exit_ok = 0,
142 ctr_drbg_seed_failed,
143 ssl_config_defaults_failed,
144 ssl_setup_failed,
145 hostname_failed,
146 socket_failed,
147 connect_failed,
148 x509_crt_parse_failed,
149 ssl_handshake_failed,
150 ssl_write_failed,
151 };
152
153
main(void)154 int main(void)
155 {
156 int ret = exit_ok;
157 mbedtls_net_context server_fd;
158 struct sockaddr_in addr;
159 #if defined(MBEDTLS_X509_CRT_PARSE_C)
160 mbedtls_x509_crt ca;
161 #endif
162
163 mbedtls_entropy_context entropy;
164 mbedtls_ctr_drbg_context ctr_drbg;
165 mbedtls_ssl_context ssl;
166 mbedtls_ssl_config conf;
167 mbedtls_ctr_drbg_init(&ctr_drbg);
168
169 /*
170 * 0. Initialize and setup stuff
171 */
172 mbedtls_net_init(&server_fd);
173 mbedtls_ssl_init(&ssl);
174 mbedtls_ssl_config_init(&conf);
175 #if defined(MBEDTLS_X509_CRT_PARSE_C)
176 mbedtls_x509_crt_init(&ca);
177 #endif
178
179 mbedtls_entropy_init(&entropy);
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
266 mbedtls_ssl_free(&ssl);
267 mbedtls_ssl_config_free(&conf);
268 mbedtls_ctr_drbg_free(&ctr_drbg);
269 mbedtls_entropy_free(&entropy);
270 #if defined(MBEDTLS_X509_CRT_PARSE_C)
271 mbedtls_x509_crt_free(&ca);
272 #endif
273
274 mbedtls_exit(ret);
275 }
276 #endif
277