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