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