xref: /openbsd/regress/lib/libssl/client/clienttest.c (revision 3cab2bb3)
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, 0x73, 0x01, 0x00, 0x00,
70 	0x6f, 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 	0x00, 0x00, 0x00, 0x00, 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, 0x18,
81 	0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a,
82 	0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17,
83 	0x00, 0x18, 0x00, 0x19, 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, 0x73, 0x01, 0x00, 0x00,
97 	0x6f, 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, 0x18,
108 	0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a,
109 	0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17,
110 	0x00, 0x18, 0x00, 0x19, 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, 0xbd, 0x01, 0x00, 0x00,
145 	0xb9, 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, 0x34, 0x00, 0x0b,
162 	0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a,
163 	0x00, 0x08, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
164 	0x00, 0x19, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d,
165 	0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01,
166 	0x06, 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03,
167 	0x08, 0x04, 0x04, 0x01, 0x04, 0x03, 0x02, 0x01,
168 	0x02, 0x03,
169 };
170 
171 struct client_hello_test {
172 	const unsigned char *desc;
173 	const int protocol;
174 	const size_t random_start;
175 	const SSL_METHOD *(*ssl_method)(void);
176 	const long ssl_options;
177 };
178 
179 static struct client_hello_test client_hello_tests[] = {
180 	{
181 		.desc = "DTLSv1 client",
182 		.protocol = DTLS1_VERSION,
183 		.random_start = DTLS_RANDOM_OFFSET,
184 		.ssl_method = DTLSv1_client_method,
185 	},
186 	{
187 		.desc = "TLSv1 client",
188 		.protocol = TLS1_VERSION,
189 		.random_start = SSL3_RANDOM_OFFSET,
190 		.ssl_method = TLSv1_client_method,
191 	},
192 	{
193 		.desc = "TLSv1_1 client",
194 		.protocol = TLS1_1_VERSION,
195 		.random_start = SSL3_RANDOM_OFFSET,
196 		.ssl_method = TLSv1_1_client_method,
197 	},
198 	{
199 		.desc = "TLSv1_2 client",
200 		.protocol = TLS1_2_VERSION,
201 		.random_start = SSL3_RANDOM_OFFSET,
202 		.ssl_method = TLSv1_2_client_method,
203 	},
204 #if 0
205 	{
206 		.desc = "SSLv23 default",
207 		.protocol = TLS1_3_VERSION,
208 		.random_start = SSL3_RANDOM_OFFSET,
209 		.ssl_method = SSLv23_client_method,
210 		.ssl_options = 0,
211 	},
212 #endif
213 	{
214 		.desc = "SSLv23 default (no TLSv1.3)",
215 		.protocol = TLS1_2_VERSION,
216 		.random_start = SSL3_RANDOM_OFFSET,
217 		.ssl_method = SSLv23_client_method,
218 		.ssl_options = SSL_OP_NO_TLSv1_3,
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 #if 0
235 	{
236 		.desc = "TLS default",
237 		.protocol = TLS1_3_VERSION,
238 		.random_start = SSL3_RANDOM_OFFSET,
239 		.ssl_method = TLS_client_method,
240 		.ssl_options = 0,
241 	},
242 #endif
243 	{
244 		.desc = "TLS (no TLSv1.3)",
245 		.protocol = TLS1_2_VERSION,
246 		.random_start = SSL3_RANDOM_OFFSET,
247 		.ssl_method = TLS_client_method,
248 		.ssl_options = SSL_OP_NO_TLSv1_3,
249 	},
250 	{
251 		.desc = "TLS (no TLSv1.2)",
252 		.protocol = TLS1_1_VERSION,
253 		.random_start = SSL3_RANDOM_OFFSET,
254 		.ssl_method = TLS_client_method,
255 		.ssl_options = SSL_OP_NO_TLSv1_2,
256 	},
257 	{
258 		.desc = "TLS (no TLSv1.1)",
259 		.protocol = TLS1_VERSION,
260 		.random_start = SSL3_RANDOM_OFFSET,
261 		.ssl_method = TLS_client_method,
262 		.ssl_options = SSL_OP_NO_TLSv1_1,
263 	},
264 #if 0
265 	{
266 		.desc = "TLS (no TLSv1.0, no TLSv1.1)",
267 		.protocol = TLS1_3_VERSION,
268 		.random_start = SSL3_RANDOM_OFFSET,
269 		.ssl_method = TLS_client_method,
270 		.ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
271 	},
272 #endif
273 #if 0
274 	{
275 		.desc = "TLS (no TLSv1.0, no TLSv1.1, no TLSv1.2)",
276 		.protocol = TLS1_3_VERSION,
277 		.random_start = SSL3_RANDOM_OFFSET,
278 		.ssl_method = TLS_client_method,
279 		.ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2,
280 	},
281 #endif
282 };
283 
284 #define N_CLIENT_HELLO_TESTS \
285     (sizeof(client_hello_tests) / sizeof(*client_hello_tests))
286 
287 static void
288 hexdump(const unsigned char *buf, size_t len)
289 {
290 	size_t i;
291 
292 	for (i = 1; i <= len; i++)
293 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 && i != len ? "" : "\n");
294 
295 	fprintf(stderr, "\n");
296 }
297 
298 static inline int
299 ssl_aes_is_accelerated(void)
300 {
301 #if defined(__i386__) || defined(__x86_64__)
302 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
303 #else
304 	return (0);
305 #endif
306 }
307 
308 static int
309 make_client_hello(int protocol, char **out, size_t *outlen)
310 {
311 	size_t client_hello_len, cipher_list_len, cipher_list_offset;
312 	const char *client_hello, *cipher_list;
313 	char *p;
314 
315 	*out = NULL;
316 	*outlen = 0;
317 
318 	switch (protocol) {
319 	case DTLS1_VERSION:
320 		client_hello = client_hello_dtls1;
321 		client_hello_len = sizeof(client_hello_dtls1);
322 		cipher_list = cipher_list_dtls1;
323 		cipher_list_len = sizeof(cipher_list_dtls1);
324 		cipher_list_offset = DTLS_CIPHER_OFFSET;
325 		break;
326 
327 	case TLS1_VERSION:
328 		client_hello = client_hello_tls10;
329 		client_hello_len = sizeof(client_hello_tls10);
330 		cipher_list = cipher_list_tls10;
331 		cipher_list_len = sizeof(cipher_list_tls10);
332 		cipher_list_offset = SSL3_CIPHER_OFFSET;
333 		break;
334 
335 	case TLS1_1_VERSION:
336 		client_hello = client_hello_tls11;
337 		client_hello_len = sizeof(client_hello_tls11);
338 		cipher_list = cipher_list_tls11;
339 		cipher_list_len = sizeof(cipher_list_tls11);
340 		cipher_list_offset = SSL3_CIPHER_OFFSET;
341 		break;
342 
343 	case TLS1_2_VERSION:
344 		client_hello = client_hello_tls12;
345 		client_hello_len = sizeof(client_hello_tls12);
346 		if (ssl_aes_is_accelerated())
347 			cipher_list = cipher_list_tls12_aes;
348 		else
349 			cipher_list = cipher_list_tls12_chacha;
350 		cipher_list_len = sizeof(cipher_list_tls12_chacha);
351 		cipher_list_offset = SSL3_CIPHER_OFFSET;
352 		break;
353 
354 	default:
355 		return (-1);
356 	}
357 
358 	if ((p = malloc(client_hello_len)) == NULL)
359 		return (-1);
360 
361 	memcpy(p, client_hello, client_hello_len);
362 	memcpy(p + cipher_list_offset, cipher_list, cipher_list_len);
363 
364 	*out = p;
365 	*outlen = client_hello_len;
366 
367 	return (0);
368 }
369 
370 static int
371 client_hello_test(int testno, struct client_hello_test *cht)
372 {
373 	BIO *rbio = NULL, *wbio = NULL;
374 	SSL_CTX *ssl_ctx = NULL;
375 	SSL *ssl = NULL;
376 	char *client_hello = NULL;
377 	size_t client_hello_len;
378 	char *wbuf, rbuf[1];
379 	int ret = 1;
380 	long len;
381 
382 	fprintf(stderr, "Test %i - %s\n", testno, cht->desc);
383 
384 	/* Providing a small buf causes *_get_server_hello() to return. */
385 	if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) {
386 		fprintf(stderr, "Failed to setup rbio\n");
387 		goto failure;
388 	}
389 	if ((wbio = BIO_new(BIO_s_mem())) == NULL) {
390 		fprintf(stderr, "Failed to setup wbio\n");
391 		goto failure;
392 	}
393 
394 	if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) {
395 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
396 		goto failure;
397 	}
398 
399 	SSL_CTX_set_options(ssl_ctx, cht->ssl_options);
400 
401 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
402 		fprintf(stderr, "SSL_new() returned NULL\n");
403 		goto failure;
404 	}
405 
406 	rbio->references = 2;
407 	wbio->references = 2;
408 
409 	SSL_set_bio(ssl, rbio, wbio);
410 
411 	if (SSL_connect(ssl) != 0) {
412 		fprintf(stderr, "SSL_connect() returned non-zero\n");
413 		goto failure;
414 	}
415 
416 	len = BIO_get_mem_data(wbio, &wbuf);
417 
418 	if (make_client_hello(cht->protocol, &client_hello,
419 	    &client_hello_len) != 0)
420 		errx(1, "failed to make client hello");
421 
422 	if ((size_t)len != client_hello_len) {
423 		fprintf(stderr, "FAIL: test returned ClientHello length %li, "
424 		    "want %zu\n", len, client_hello_len);
425 		fprintf(stderr, "received:\n");
426 		hexdump(wbuf, len);
427 		fprintf(stderr, "test data:\n");
428 		hexdump(client_hello, client_hello_len);
429 		fprintf(stderr, "\n");
430 		goto failure;
431 	}
432 
433 	/* We expect the client random to differ. */
434 	if (memcmp(&client_hello[cht->random_start], &wbuf[cht->random_start],
435 	    SSL3_RANDOM_SIZE) == 0) {
436 		fprintf(stderr, "FAIL: ClientHello has zeroed random\n");
437 		goto failure;
438 	}
439 
440 	memset(&wbuf[cht->random_start], 0, SSL3_RANDOM_SIZE);
441 
442 	if (memcmp(client_hello, wbuf, client_hello_len) != 0) {
443 		fprintf(stderr, "FAIL: ClientHello differs:\n");
444 		fprintf(stderr, "received:\n");
445 		hexdump(wbuf, len);
446 		fprintf(stderr, "test data:\n");
447 		hexdump(client_hello, client_hello_len);
448 		fprintf(stderr, "\n");
449 		goto failure;
450 	}
451 
452 	ret = 0;
453 
454  failure:
455 	SSL_CTX_free(ssl_ctx);
456 	SSL_free(ssl);
457 
458 	rbio->references = 1;
459 	wbio->references = 1;
460 
461 	BIO_free(rbio);
462 	BIO_free(wbio);
463 
464 	free(client_hello);
465 
466 	return (ret);
467 }
468 
469 int
470 main(int argc, char **argv)
471 {
472 	int failed = 0;
473 	size_t i;
474 
475 	SSL_library_init();
476 
477 	for (i = 0; i < N_CLIENT_HELLO_TESTS; i++)
478 		failed |= client_hello_test(i, &client_hello_tests[i]);
479 
480 	return (failed);
481 }
482