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 {
142 exit_ok = 0,
143 ctr_drbg_seed_failed,
144 ssl_config_defaults_failed,
145 ssl_setup_failed,
146 hostname_failed,
147 socket_failed,
148 connect_failed,
149 x509_crt_parse_failed,
150 ssl_handshake_failed,
151 ssl_write_failed,
152 };
153
154
main(void)155 int main( void )
156 {
157 int ret = exit_ok;
158 mbedtls_net_context server_fd;
159 struct sockaddr_in addr;
160 #if defined(MBEDTLS_X509_CRT_PARSE_C)
161 mbedtls_x509_crt ca;
162 #endif
163
164 mbedtls_entropy_context entropy;
165 mbedtls_ctr_drbg_context ctr_drbg;
166 mbedtls_ssl_context ssl;
167 mbedtls_ssl_config conf;
168 mbedtls_ctr_drbg_init( &ctr_drbg );
169
170 /*
171 * 0. Initialize and setup stuff
172 */
173 mbedtls_net_init( &server_fd );
174 mbedtls_ssl_init( &ssl );
175 mbedtls_ssl_config_init( &conf );
176 #if defined(MBEDTLS_X509_CRT_PARSE_C)
177 mbedtls_x509_crt_init( &ca );
178 #endif
179
180 mbedtls_entropy_init( &entropy );
181 if( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
182 (const unsigned char *) pers, strlen( pers ) ) != 0 )
183 {
184 ret = ctr_drbg_seed_failed;
185 goto exit;
186 }
187
188 if( mbedtls_ssl_config_defaults( &conf,
189 MBEDTLS_SSL_IS_CLIENT,
190 MBEDTLS_SSL_TRANSPORT_STREAM,
191 MBEDTLS_SSL_PRESET_DEFAULT ) != 0 )
192 {
193 ret = ssl_config_defaults_failed;
194 goto exit;
195 }
196
197 mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
198
199 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
200 mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
201 (const unsigned char *) psk_id, sizeof( psk_id ) - 1 );
202 #endif
203
204 #if defined(MBEDTLS_X509_CRT_PARSE_C)
205 if( mbedtls_x509_crt_parse_der( &ca, ca_cert, sizeof( ca_cert ) ) != 0 )
206 {
207 ret = x509_crt_parse_failed;
208 goto exit;
209 }
210
211 mbedtls_ssl_conf_ca_chain( &conf, &ca, NULL );
212 mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
213 #endif
214
215 if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
216 {
217 ret = ssl_setup_failed;
218 goto exit;
219 }
220
221 #if defined(MBEDTLS_X509_CRT_PARSE_C)
222 if( mbedtls_ssl_set_hostname( &ssl, HOSTNAME ) != 0 )
223 {
224 ret = hostname_failed;
225 goto exit;
226 }
227 #endif
228
229 /*
230 * 1. Start the connection
231 */
232 memset( &addr, 0, sizeof( addr ) );
233 addr.sin_family = AF_INET;
234
235 ret = 1; /* for endianness detection */
236 addr.sin_port = *((char *) &ret) == ret ? PORT_LE : PORT_BE;
237 addr.sin_addr.s_addr = *((char *) &ret) == ret ? ADDR_LE : ADDR_BE;
238 ret = 0;
239
240 if( ( server_fd.fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
241 {
242 ret = socket_failed;
243 goto exit;
244 }
245
246 if( connect( server_fd.fd,
247 (const struct sockaddr *) &addr, sizeof( addr ) ) < 0 )
248 {
249 ret = connect_failed;
250 goto exit;
251 }
252
253 mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
254
255 if( mbedtls_ssl_handshake( &ssl ) != 0 )
256 {
257 ret = ssl_handshake_failed;
258 goto exit;
259 }
260
261 /*
262 * 2. Write the GET request and close the connection
263 */
264 if( mbedtls_ssl_write( &ssl, (const unsigned char *) GET_REQUEST,
265 sizeof( GET_REQUEST ) - 1 ) <= 0 )
266 {
267 ret = ssl_write_failed;
268 goto exit;
269 }
270
271 mbedtls_ssl_close_notify( &ssl );
272
273 exit:
274 mbedtls_net_free( &server_fd );
275
276 mbedtls_ssl_free( &ssl );
277 mbedtls_ssl_config_free( &conf );
278 mbedtls_ctr_drbg_free( &ctr_drbg );
279 mbedtls_entropy_free( &entropy );
280 #if defined(MBEDTLS_X509_CRT_PARSE_C)
281 mbedtls_x509_crt_free( &ca );
282 #endif
283
284 mbedtls_exit( ret );
285 }
286 #endif
287