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