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