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