xref: /openbsd-src/regress/lib/libssl/client/clienttest.c (revision c7e8ea31cd41a963f06f0a8ba93948b06aa6b4a4)
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 	0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0xff, 0x85,
124 	0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d,
125 	0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84,
126 	0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23,
127 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67,
128 	0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c,
129 	0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41,
130 	0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0x00, 0x04,
131 	0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a,
132 	0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
133 };
134 
135 static unsigned char cipher_list_tls12_chacha[] = {
136 	0xcc, 0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xcc, 0x14,
137 	0xcc, 0x13, 0xcc, 0x15, 0xc0, 0x30, 0xc0, 0x2c,
138 	0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a,
139 	0x00, 0x9f, 0x00, 0x6b, 0x00, 0x39, 0xff, 0x85,
140 	0x00, 0xc4, 0x00, 0x88, 0x00, 0x81, 0x00, 0x9d,
141 	0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84,
142 	0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23,
143 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67,
144 	0x00, 0x33, 0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c,
145 	0x00, 0x3c, 0x00, 0x2f, 0x00, 0xba, 0x00, 0x41,
146 	0xc0, 0x11, 0xc0, 0x07, 0x00, 0x05, 0x00, 0x04,
147 	0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a,
148 	0x00, 0x15, 0x00, 0x09, 0x00, 0xff,
149 };
150 
151 static unsigned char client_hello_tls12[] = {
152 	0x16, 0x03, 0x01, 0x00, 0xc9, 0x01, 0x00, 0x00,
153 	0xc5, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
154 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 	0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xcc, 0xa9,
158 	0xcc, 0xa8, 0xcc, 0xaa, 0xcc, 0x14, 0xcc, 0x13,
159 	0xcc, 0x15, 0xc0, 0x30, 0xc0, 0x2c, 0xc0, 0x28,
160 	0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a, 0x00, 0x9f,
161 	0x00, 0x6b, 0x00, 0x39, 0xff, 0x85, 0x00, 0xc4,
162 	0x00, 0x88, 0x00, 0x81, 0x00, 0x9d, 0x00, 0x3d,
163 	0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f,
164 	0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13,
165 	0xc0, 0x09, 0x00, 0x9e, 0x00, 0x67, 0x00, 0x33,
166 	0x00, 0xbe, 0x00, 0x45, 0x00, 0x9c, 0x00, 0x3c,
167 	0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, 0xc0, 0x11,
168 	0xc0, 0x07, 0x00, 0x05, 0x00, 0x04, 0xc0, 0x12,
169 	0xc0, 0x08, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x15,
170 	0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x36,
171 	0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a,
172 	0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17,
173 	0x00, 0x18, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d,
174 	0x00, 0x1c, 0x00, 0x1a, 0x06, 0x01, 0x06, 0x03,
175 	0xef, 0xef, 0x05, 0x01, 0x05, 0x03, 0x04, 0x01,
176 	0x04, 0x03, 0xee, 0xee, 0xed, 0xed, 0x03, 0x01,
177 	0x03, 0x03, 0x02, 0x01, 0x02, 0x03,
178 };
179 
180 struct client_hello_test {
181 	const unsigned char *desc;
182 	const int protocol;
183 	const size_t random_start;
184 	const SSL_METHOD *(*ssl_method)(void);
185 	const long ssl_options;
186 };
187 
188 static struct client_hello_test client_hello_tests[] = {
189 	{
190 		.desc = "DTLSv1 client",
191 		.protocol = DTLS1_VERSION,
192 		.random_start = DTLS_RANDOM_OFFSET,
193 		.ssl_method = DTLSv1_client_method,
194 	},
195 	{
196 		.desc = "TLSv1 client",
197 		.protocol = TLS1_VERSION,
198 		.random_start = SSL3_RANDOM_OFFSET,
199 		.ssl_method = TLSv1_client_method,
200 	},
201 	{
202 		.desc = "TLSv1_1 client",
203 		.protocol = TLS1_1_VERSION,
204 		.random_start = SSL3_RANDOM_OFFSET,
205 		.ssl_method = TLSv1_1_client_method,
206 	},
207 	{
208 		.desc = "TLSv1_2 client",
209 		.protocol = TLS1_2_VERSION,
210 		.random_start = SSL3_RANDOM_OFFSET,
211 		.ssl_method = TLSv1_2_client_method,
212 	},
213 	{
214 		.desc = "SSLv23 default",
215 		.protocol = TLS1_2_VERSION,
216 		.random_start = SSL3_RANDOM_OFFSET,
217 		.ssl_method = SSLv23_client_method,
218 		.ssl_options = 0,
219 	},
220 	{
221 		.desc = "SSLv23 (no TLSv1.2)",
222 		.protocol = TLS1_1_VERSION,
223 		.random_start = SSL3_RANDOM_OFFSET,
224 		.ssl_method = SSLv23_client_method,
225 		.ssl_options = SSL_OP_NO_TLSv1_2,
226 	},
227 	{
228 		.desc = "SSLv23 (no TLSv1.1)",
229 		.protocol = TLS1_VERSION,
230 		.random_start = SSL3_RANDOM_OFFSET,
231 		.ssl_method = SSLv23_client_method,
232 		.ssl_options = SSL_OP_NO_TLSv1_1,
233 	},
234 	{
235 		.desc = "TLS default",
236 		.protocol = TLS1_2_VERSION,
237 		.random_start = SSL3_RANDOM_OFFSET,
238 		.ssl_method = TLS_client_method,
239 		.ssl_options = 0,
240 	},
241 	{
242 		.desc = "TLS (no TLSv1.2)",
243 		.protocol = TLS1_1_VERSION,
244 		.random_start = SSL3_RANDOM_OFFSET,
245 		.ssl_method = TLS_client_method,
246 		.ssl_options = SSL_OP_NO_TLSv1_2,
247 	},
248 	{
249 		.desc = "TLS (no TLSv1.1)",
250 		.protocol = TLS1_VERSION,
251 		.random_start = SSL3_RANDOM_OFFSET,
252 		.ssl_method = TLS_client_method,
253 		.ssl_options = SSL_OP_NO_TLSv1_1,
254 	},
255 	{
256 		.desc = "TLS (no TLSv1.0, no TLSv1.1)",
257 		.protocol = TLS1_2_VERSION,
258 		.random_start = SSL3_RANDOM_OFFSET,
259 		.ssl_method = TLS_client_method,
260 		.ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
261 	},
262 };
263 
264 #define N_CLIENT_HELLO_TESTS \
265     (sizeof(client_hello_tests) / sizeof(*client_hello_tests))
266 
267 static void
268 hexdump(const unsigned char *buf, size_t len)
269 {
270 	size_t i;
271 
272 	for (i = 1; i <= len; i++)
273 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
274 
275 	fprintf(stderr, "\n");
276 }
277 
278 static inline int
279 ssl_aes_is_accelerated(void)
280 {
281 #if defined(__i386__) || defined(__x86_64__)
282 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
283 #else
284 	return (0);
285 #endif
286 }
287 
288 static int
289 make_client_hello(int protocol, char **out, size_t *outlen)
290 {
291 	size_t client_hello_len, cipher_list_len, cipher_list_offset;
292 	const char *client_hello, *cipher_list;
293 	char *p;
294 
295 	*out = NULL;
296 	*outlen = 0;
297 
298 	switch (protocol) {
299 	case DTLS1_VERSION:
300 		client_hello = client_hello_dtls1;
301 		client_hello_len = sizeof(client_hello_dtls1);
302 		cipher_list = cipher_list_dtls1;
303 		cipher_list_len = sizeof(cipher_list_dtls1);
304 		cipher_list_offset = DTLS_CIPHER_OFFSET;
305 		break;
306 
307 	case TLS1_VERSION:
308 		client_hello = client_hello_tls10;
309 		client_hello_len = sizeof(client_hello_tls10);
310 		cipher_list = cipher_list_tls10;
311 		cipher_list_len = sizeof(cipher_list_tls10);
312 		cipher_list_offset = SSL3_CIPHER_OFFSET;
313 		break;
314 
315 	case TLS1_1_VERSION:
316 		client_hello = client_hello_tls11;
317 		client_hello_len = sizeof(client_hello_tls11);
318 		cipher_list = cipher_list_tls11;
319 		cipher_list_len = sizeof(cipher_list_tls11);
320 		cipher_list_offset = SSL3_CIPHER_OFFSET;
321 		break;
322 
323 	case TLS1_2_VERSION:
324 		client_hello = client_hello_tls12;
325 		client_hello_len = sizeof(client_hello_tls12);
326 		if (ssl_aes_is_accelerated() == 1)
327 			cipher_list = cipher_list_tls12_aes;
328 		else
329 			cipher_list = cipher_list_tls12_chacha;
330 		cipher_list_len = sizeof(cipher_list_tls12_chacha);
331 		cipher_list_offset = SSL3_CIPHER_OFFSET;
332 		break;
333 
334 	default:
335 		return (-1);
336 	}
337 
338 	if ((p = malloc(client_hello_len)) == NULL)
339 		return (-1);
340 
341 	memcpy(p, client_hello, client_hello_len);
342 	memcpy(p + cipher_list_offset, cipher_list, cipher_list_len);
343 
344 	*out = p;
345 	*outlen = client_hello_len;
346 
347 	return (0);
348 }
349 
350 static int
351 client_hello_test(int testno, struct client_hello_test *cht)
352 {
353 	BIO *rbio = NULL, *wbio = NULL;
354 	SSL_CTX *ssl_ctx = NULL;
355 	SSL *ssl = NULL;
356 	char *client_hello = NULL;
357 	size_t client_hello_len;
358 	char *wbuf, rbuf[1];
359 	int ret = 1;
360 	size_t i;
361 	long len;
362 
363 	fprintf(stderr, "Test %i - %s\n", testno, cht->desc);
364 
365 	/* Providing a small buf causes *_get_server_hello() to return. */
366 	if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) {
367 		fprintf(stderr, "Failed to setup rbio\n");
368 		goto failure;
369 	}
370 	if ((wbio = BIO_new(BIO_s_mem())) == NULL) {
371 		fprintf(stderr, "Failed to setup wbio\n");
372 		goto failure;
373 	}
374 
375 	if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) {
376 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
377 		goto failure;
378 	}
379 
380 	SSL_CTX_set_options(ssl_ctx, cht->ssl_options);
381 
382 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
383 		fprintf(stderr, "SSL_new() returned NULL\n");
384 		goto failure;
385 	}
386 
387 	rbio->references = 2;
388 	wbio->references = 2;
389 
390 	SSL_set_bio(ssl, rbio, wbio);
391 
392 	if (SSL_connect(ssl) != 0) {
393 		fprintf(stderr, "SSL_connect() returned non-zero\n");
394 		goto failure;
395 	}
396 
397 	len = BIO_get_mem_data(wbio, &wbuf);
398 
399 	if (make_client_hello(cht->protocol, &client_hello,
400 	    &client_hello_len) != 0)
401 		goto failure;
402 
403 	if ((size_t)len != client_hello_len) {
404 		fprintf(stderr, "FAIL: test returned ClientHello length %li, "
405 		    "want %zu\n", len, client_hello_len);
406 		fprintf(stderr, "received:\n");
407 		hexdump(wbuf, len);
408 		goto failure;
409 	}
410 
411 	/* We expect the client random to differ. */
412 	i = cht->random_start + SSL3_RANDOM_SIZE;
413 	if (memcmp(client_hello, wbuf, cht->random_start) != 0 ||
414 	    memcmp(&client_hello[cht->random_start],
415 		&wbuf[cht->random_start], SSL3_RANDOM_SIZE) == 0 ||
416 	    memcmp(&client_hello[i], &wbuf[i], len - i) != 0) {
417 		fprintf(stderr, "FAIL: ClientHello differs:\n");
418 		fprintf(stderr, "received:\n");
419 		hexdump(wbuf, len);
420 		fprintf(stderr, "test data:\n");
421 		hexdump(client_hello, client_hello_len);
422 		fprintf(stderr, "\n");
423 		goto failure;
424 	}
425 
426 	ret = 0;
427 
428 failure:
429 	SSL_CTX_free(ssl_ctx);
430 	SSL_free(ssl);
431 
432 	rbio->references = 1;
433 	wbio->references = 1;
434 
435 	BIO_free(rbio);
436 	BIO_free(wbio);
437 
438 	free(client_hello);
439 
440 	return (ret);
441 }
442 
443 int
444 main(int argc, char **argv)
445 {
446 	int failed = 0;
447 	size_t i;
448 
449 	SSL_library_init();
450 
451 	for (i = 0; i < N_CLIENT_HELLO_TESTS; i++)
452 		failed |= client_hello_test(i, &client_hello_tests[i]);
453 
454 	return (failed);
455 }
456