xref: /openbsd-src/regress/lib/libssl/client/clienttest.c (revision 22088883e4638b01ad57a75b2bb292affdc02d22)
1 /*
2  * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <openssl/ssl.h>
18 
19 #include <openssl/dtls1.h>
20 #include <openssl/ssl3.h>
21 
22 #include <err.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #define DTLS_HM_OFFSET (DTLS1_RT_HEADER_LENGTH + DTLS1_HM_HEADER_LENGTH)
27 #define DTLS_RANDOM_OFFSET (DTLS_HM_OFFSET + 2)
28 #define DTLS_CIPHER_OFFSET (DTLS_HM_OFFSET + 38)
29 
30 #define SSL3_HM_OFFSET (SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)
31 #define SSL3_RANDOM_OFFSET (SSL3_HM_OFFSET + 2)
32 #define SSL3_CIPHER_OFFSET (SSL3_HM_OFFSET + 37)
33 
34 static unsigned char cipher_list_dtls1[] = {
35 	0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85,
36 	0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84,
37 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45,
38 	0x00, 0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08,
39 	0x00, 0x16, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09,
40 	0x00, 0xff,
41 };
42 
43 static unsigned char client_hello_dtls1[] = {
44 	0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
45 	0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00,
46 	0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 	0x58, 0xfe, 0xff, 0xc3, 0xd6, 0x19, 0xf8, 0x5d,
48 	0x6a, 0xe3, 0x6d, 0x16, 0x4a, 0xf7, 0x8f, 0x8e,
49 	0x4a, 0x12, 0x87, 0xcf, 0x07, 0x99, 0xa7, 0x92,
50 	0x40, 0xbd, 0x06, 0x9f, 0xe9, 0xd2, 0x68, 0x84,
51 	0xff, 0x6f, 0xe8, 0x00, 0x00, 0x00, 0x2a, 0xc0,
52 	0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00,
53 	0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0,
54 	0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00,
55 	0x2f, 0x00, 0x41, 0xc0, 0x12, 0xc0, 0x08, 0x00,
56 	0x16, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00,
57 	0xff, 0x01, 0x00, 0x00, 0x04, 0x00, 0x23, 0x00,
58 	0x00,
59 };
60 
61 static unsigned char cipher_list_tls10[] = {
62 	0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85,
63 	0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84,
64 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45,
65 	0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07,
66 	0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08,
67 	0x00, 0x16, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09,
68 	0x00, 0xff,
69 };
70 
71 static unsigned char client_hello_tls10[] = {
72 	0x16, 0x03, 0x01, 0x00, 0x75, 0x01, 0x00, 0x00,
73 	0x71, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
74 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 	0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xc0, 0x14,
78 	0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88,
79 	0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13,
80 	0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f,
81 	0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05,
82 	0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16,
83 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
84 	0x01, 0x00, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x02,
85 	0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06,
86 	0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x23,
87 	0x00, 0x00,
88 };
89 
90 static unsigned char cipher_list_tls11[] = {
91 	0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85,
92 	0x00, 0x88, 0x00, 0x81, 0x00, 0x35, 0x00, 0x84,
93 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x33, 0x00, 0x45,
94 	0x00, 0x2f, 0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07,
95 	0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08,
96 	0x00, 0x16, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09,
97 	0x00, 0xff,
98 };
99 
100 static unsigned char client_hello_tls11[] = {
101 	0x16, 0x03, 0x01, 0x00, 0x75, 0x01, 0x00, 0x00,
102 	0x71, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
103 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 	0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xc0, 0x14,
107 	0xc0, 0x0a, 0x00, 0x39, 0xff, 0x85, 0x00, 0x88,
108 	0x00, 0x81, 0x00, 0x35, 0x00, 0x84, 0xc0, 0x13,
109 	0xc0, 0x09, 0x00, 0x33, 0x00, 0x45, 0x00, 0x2f,
110 	0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05,
111 	0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16,
112 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
113 	0x01, 0x00, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x02,
114 	0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06,
115 	0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x23,
116 	0x00, 0x00,
117 };
118 
119 static unsigned char cipher_list_tls12_aes[] = {
120 	0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24,
121 	0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b,
122 	0x00, 0x39, 0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa,
123 	0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81,
124 	0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0,
125 	0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27,
126 	0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e,
127 	0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45,
128 	0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba,
129 	0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05,
130 	0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16,
131 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
132 };
133 
134 static unsigned char cipher_list_tls12_chacha[] = {
135 	0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30,
136 	0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14,
137 	0xc0, 0x0a, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39,
138 	0xff, 0x85, 0x00, 0xc4, 0x00, 0x88, 0x00, 0x81,
139 	0x00, 0x9d, 0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0,
140 	0x00, 0x84, 0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27,
141 	0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e,
142 	0x00, 0x67, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x45,
143 	0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba,
144 	0x00, 0x41, 0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05,
145 	0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16,
146 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
147 };
148 
149 static unsigned char client_hello_tls12[] = {
150 	0x16, 0x03, 0x01, 0x00, 0xc3, 0x01, 0x00, 0x00,
151 	0xbf, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
152 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0xa9,
156 	0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x30, 0xc0, 0x2c,
157 	0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a,
158 	0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, 0xff, 0x85,
159 	0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d,
160 	0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84,
161 	0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23,
162 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67,
163 	0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c,
164 	0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41,
165 	0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0x00, 0x04,
166 	0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a,
167 	0x00, 0x15, 0x00, 0x09, 0x00, 0xff, 0x01, 0x00,
168 	0x00, 0x36, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
169 	0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d,
170 	0x00, 0x17, 0x00, 0x18, 0x00, 0x23, 0x00, 0x00,
171 	0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, 0x06, 0x01,
172 	0x06, 0x03, 0xef, 0xef, 0x05, 0x01, 0x05, 0x03,
173 	0x04, 0x01, 0x04, 0x03, 0xee, 0xee, 0xed, 0xed,
174 	0x03, 0x01, 0x03, 0x03, 0x02, 0x01, 0x02, 0x03,
175 };
176 
177 struct client_hello_test {
178 	const unsigned char *desc;
179 	const int protocol;
180 	const size_t random_start;
181 	const SSL_METHOD *(*ssl_method)(void);
182 	const long ssl_options;
183 };
184 
185 static struct client_hello_test client_hello_tests[] = {
186 	{
187 		.desc = "DTLSv1 client",
188 		.protocol = DTLS1_VERSION,
189 		.random_start = DTLS_RANDOM_OFFSET,
190 		.ssl_method = DTLSv1_client_method,
191 	},
192 	{
193 		.desc = "TLSv1 client",
194 		.protocol = TLS1_VERSION,
195 		.random_start = SSL3_RANDOM_OFFSET,
196 		.ssl_method = TLSv1_client_method,
197 	},
198 	{
199 		.desc = "TLSv1_1 client",
200 		.protocol = TLS1_1_VERSION,
201 		.random_start = SSL3_RANDOM_OFFSET,
202 		.ssl_method = TLSv1_1_client_method,
203 	},
204 	{
205 		.desc = "TLSv1_2 client",
206 		.protocol = TLS1_2_VERSION,
207 		.random_start = SSL3_RANDOM_OFFSET,
208 		.ssl_method = TLSv1_2_client_method,
209 	},
210 	{
211 		.desc = "SSLv23 default",
212 		.protocol = TLS1_2_VERSION,
213 		.random_start = SSL3_RANDOM_OFFSET,
214 		.ssl_method = SSLv23_client_method,
215 		.ssl_options = 0,
216 	},
217 	{
218 		.desc = "SSLv23 (no TLSv1.2)",
219 		.protocol = TLS1_1_VERSION,
220 		.random_start = SSL3_RANDOM_OFFSET,
221 		.ssl_method = SSLv23_client_method,
222 		.ssl_options = SSL_OP_NO_TLSv1_2,
223 	},
224 	{
225 		.desc = "SSLv23 (no TLSv1.1)",
226 		.protocol = TLS1_VERSION,
227 		.random_start = SSL3_RANDOM_OFFSET,
228 		.ssl_method = SSLv23_client_method,
229 		.ssl_options = SSL_OP_NO_TLSv1_1,
230 	},
231 	{
232 		.desc = "TLS default",
233 		.protocol = TLS1_2_VERSION,
234 		.random_start = SSL3_RANDOM_OFFSET,
235 		.ssl_method = TLS_client_method,
236 		.ssl_options = 0,
237 	},
238 	{
239 		.desc = "TLS (no TLSv1.2)",
240 		.protocol = TLS1_1_VERSION,
241 		.random_start = SSL3_RANDOM_OFFSET,
242 		.ssl_method = TLS_client_method,
243 		.ssl_options = SSL_OP_NO_TLSv1_2,
244 	},
245 	{
246 		.desc = "TLS (no TLSv1.1)",
247 		.protocol = TLS1_VERSION,
248 		.random_start = SSL3_RANDOM_OFFSET,
249 		.ssl_method = TLS_client_method,
250 		.ssl_options = SSL_OP_NO_TLSv1_1,
251 	},
252 	{
253 		.desc = "TLS (no TLSv1.0, no TLSv1.1)",
254 		.protocol = TLS1_2_VERSION,
255 		.random_start = SSL3_RANDOM_OFFSET,
256 		.ssl_method = TLS_client_method,
257 		.ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
258 	},
259 };
260 
261 #define N_CLIENT_HELLO_TESTS \
262     (sizeof(client_hello_tests) / sizeof(*client_hello_tests))
263 
264 static void
265 hexdump(const unsigned char *buf, size_t len)
266 {
267 	size_t i;
268 
269 	for (i = 1; i <= len; i++)
270 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
271 
272 	fprintf(stderr, "\n");
273 }
274 
275 static inline int
276 ssl_aes_is_accelerated(void)
277 {
278 #if defined(__i386__) || defined(__x86_64__)
279 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
280 #else
281 	return (0);
282 #endif
283 }
284 
285 static int
286 make_client_hello(int protocol, char **out, size_t *outlen)
287 {
288 	size_t client_hello_len, cipher_list_len, cipher_list_offset;
289 	const char *client_hello, *cipher_list;
290 	char *p;
291 
292 	*out = NULL;
293 	*outlen = 0;
294 
295 	switch (protocol) {
296 	case DTLS1_VERSION:
297 		client_hello = client_hello_dtls1;
298 		client_hello_len = sizeof(client_hello_dtls1);
299 		cipher_list = cipher_list_dtls1;
300 		cipher_list_len = sizeof(cipher_list_dtls1);
301 		cipher_list_offset = DTLS_CIPHER_OFFSET;
302 		break;
303 
304 	case TLS1_VERSION:
305 		client_hello = client_hello_tls10;
306 		client_hello_len = sizeof(client_hello_tls10);
307 		cipher_list = cipher_list_tls10;
308 		cipher_list_len = sizeof(cipher_list_tls10);
309 		cipher_list_offset = SSL3_CIPHER_OFFSET;
310 		break;
311 
312 	case TLS1_1_VERSION:
313 		client_hello = client_hello_tls11;
314 		client_hello_len = sizeof(client_hello_tls11);
315 		cipher_list = cipher_list_tls11;
316 		cipher_list_len = sizeof(cipher_list_tls11);
317 		cipher_list_offset = SSL3_CIPHER_OFFSET;
318 		break;
319 
320 	case TLS1_2_VERSION:
321 		client_hello = client_hello_tls12;
322 		client_hello_len = sizeof(client_hello_tls12);
323 		if (ssl_aes_is_accelerated() == 1)
324 			cipher_list = cipher_list_tls12_aes;
325 		else
326 			cipher_list = cipher_list_tls12_chacha;
327 		cipher_list_len = sizeof(cipher_list_tls12_chacha);
328 		cipher_list_offset = SSL3_CIPHER_OFFSET;
329 		break;
330 
331 	default:
332 		return (-1);
333 	}
334 
335 	if ((p = malloc(client_hello_len)) == NULL)
336 		return (-1);
337 
338 	memcpy(p, client_hello, client_hello_len);
339 	memcpy(p + cipher_list_offset, cipher_list, cipher_list_len);
340 
341 	*out = p;
342 	*outlen = client_hello_len;
343 
344 	return (0);
345 }
346 
347 static int
348 client_hello_test(int testno, struct client_hello_test *cht)
349 {
350 	BIO *rbio = NULL, *wbio = NULL;
351 	SSL_CTX *ssl_ctx = NULL;
352 	SSL *ssl = NULL;
353 	char *client_hello = NULL;
354 	size_t client_hello_len;
355 	char *wbuf, rbuf[1];
356 	int ret = 1;
357 	size_t i;
358 	long len;
359 
360 	fprintf(stderr, "Test %i - %s\n", testno, cht->desc);
361 
362 	/* Providing a small buf causes *_get_server_hello() to return. */
363 	if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) {
364 		fprintf(stderr, "Failed to setup rbio\n");
365 		goto failure;
366 	}
367 	if ((wbio = BIO_new(BIO_s_mem())) == NULL) {
368 		fprintf(stderr, "Failed to setup wbio\n");
369 		goto failure;
370 	}
371 
372 	if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) {
373 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
374 		goto failure;
375 	}
376 
377 	SSL_CTX_set_options(ssl_ctx, cht->ssl_options);
378 
379 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
380 		fprintf(stderr, "SSL_new() returned NULL\n");
381 		goto failure;
382 	}
383 
384 	rbio->references = 2;
385 	wbio->references = 2;
386 
387 	SSL_set_bio(ssl, rbio, wbio);
388 
389 	if (SSL_connect(ssl) != 0) {
390 		fprintf(stderr, "SSL_connect() returned non-zero\n");
391 		goto failure;
392 	}
393 
394 	len = BIO_get_mem_data(wbio, &wbuf);
395 
396 	if (make_client_hello(cht->protocol, &client_hello,
397 	    &client_hello_len) != 0)
398 		goto failure;
399 
400 	if ((size_t)len != client_hello_len) {
401 		fprintf(stderr, "FAIL: test returned ClientHello length %li, "
402 		    "want %zu\n", len, client_hello_len);
403 		fprintf(stderr, "received:\n");
404 		hexdump(wbuf, len);
405 		goto failure;
406 	}
407 
408 	/* We expect the client random to differ. */
409 	i = cht->random_start + SSL3_RANDOM_SIZE;
410 	if (memcmp(client_hello, wbuf, cht->random_start) != 0 ||
411 	    memcmp(&client_hello[cht->random_start],
412 		&wbuf[cht->random_start], SSL3_RANDOM_SIZE) == 0 ||
413 	    memcmp(&client_hello[i], &wbuf[i], len - i) != 0) {
414 		fprintf(stderr, "FAIL: ClientHello differs:\n");
415 		fprintf(stderr, "received:\n");
416 		memset(&wbuf[cht->random_start], 0, SSL3_RANDOM_SIZE);
417 		hexdump(wbuf, len);
418 		fprintf(stderr, "test data:\n");
419 		hexdump(client_hello, client_hello_len);
420 		fprintf(stderr, "\n");
421 		goto failure;
422 	}
423 
424 	ret = 0;
425 
426 failure:
427 	SSL_CTX_free(ssl_ctx);
428 	SSL_free(ssl);
429 
430 	rbio->references = 1;
431 	wbio->references = 1;
432 
433 	BIO_free(rbio);
434 	BIO_free(wbio);
435 
436 	free(client_hello);
437 
438 	return (ret);
439 }
440 
441 int
442 main(int argc, char **argv)
443 {
444 	int failed = 0;
445 	size_t i;
446 
447 	SSL_library_init();
448 
449 	for (i = 0; i < N_CLIENT_HELLO_TESTS; i++)
450 		failed |= client_hello_test(i, &client_hello_tests[i]);
451 
452 	return (failed);
453 }
454