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