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