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