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