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