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