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