xref: /openbsd-src/regress/lib/libssl/client/clienttest.c (revision 65ec708b1721d3f97bcef0b375c91aaf510b9f44)
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, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0xff, 0x85,
156 	0x00, 0xc4, 0x00, 0xc3, 0x00, 0x88, 0x00, 0x87,
157 	0x00, 0x81, 0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a,
158 	0xc0, 0x26, 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d,
159 	0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84,
160 	0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23,
161 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e,
162 	0x00, 0x67, 0x00, 0x40, 0x00, 0x33, 0x00, 0x32,
163 	0x00, 0xbe, 0x00, 0xbd, 0x00, 0x45, 0x00, 0x44,
164 	0xc0, 0x31, 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25,
165 	0xc0, 0x0e, 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c,
166 	0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, 0x00, 0x07,
167 	0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02,
168 	0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08,
169 	0x00, 0x16, 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03,
170 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x12, 0x00, 0x09,
171 	0x00, 0xff,
172 };
173 
174 static unsigned char cipher_list_tls12_chacha[] = {
175 	0xcc, 0x14, 0xcc, 0x13, 0xcc, 0x15, 0xc0, 0x30,
176 	0xc0, 0x2c, 0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14,
177 	0xc0, 0x0a, 0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b,
178 	0x00, 0x6a, 0x00, 0x39, 0x00, 0x38, 0xff, 0x85,
179 	0x00, 0xc4, 0x00, 0xc3, 0x00, 0x88, 0x00, 0x87,
180 	0x00, 0x81, 0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a,
181 	0xc0, 0x26, 0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d,
182 	0x00, 0x3d, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x84,
183 	0xc0, 0x2f, 0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23,
184 	0xc0, 0x13, 0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e,
185 	0x00, 0x67, 0x00, 0x40, 0x00, 0x33, 0x00, 0x32,
186 	0x00, 0xbe, 0x00, 0xbd, 0x00, 0x45, 0x00, 0x44,
187 	0xc0, 0x31, 0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25,
188 	0xc0, 0x0e, 0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c,
189 	0x00, 0x2f, 0x00, 0xba, 0x00, 0x41, 0x00, 0x07,
190 	0xc0, 0x11, 0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02,
191 	0x00, 0x05, 0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08,
192 	0x00, 0x16, 0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03,
193 	0x00, 0x0a, 0x00, 0x15, 0x00, 0x12, 0x00, 0x09,
194 	0x00, 0xff,
195 };
196 
197 static unsigned char client_hello_tls12[] = {
198 	0x16, 0x03, 0x01, 0x01, 0x3b, 0x01, 0x00, 0x01,
199 	0x37, 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, 0x9a, 0xcc, 0x14,
204 	0xcc, 0x13, 0xcc, 0x15, 0xc0, 0x30, 0xc0, 0x2c,
205 	0xc0, 0x28, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x0a,
206 	0x00, 0xa3, 0x00, 0x9f, 0x00, 0x6b, 0x00, 0x6a,
207 	0x00, 0x39, 0x00, 0x38, 0xff, 0x85, 0x00, 0xc4,
208 	0x00, 0xc3, 0x00, 0x88, 0x00, 0x87, 0x00, 0x81,
209 	0xc0, 0x32, 0xc0, 0x2e, 0xc0, 0x2a, 0xc0, 0x26,
210 	0xc0, 0x0f, 0xc0, 0x05, 0x00, 0x9d, 0x00, 0x3d,
211 	0x00, 0x35, 0x00, 0xc0, 0x00, 0x84, 0xc0, 0x2f,
212 	0xc0, 0x2b, 0xc0, 0x27, 0xc0, 0x23, 0xc0, 0x13,
213 	0xc0, 0x09, 0x00, 0xa2, 0x00, 0x9e, 0x00, 0x67,
214 	0x00, 0x40, 0x00, 0x33, 0x00, 0x32, 0x00, 0xbe,
215 	0x00, 0xbd, 0x00, 0x45, 0x00, 0x44, 0xc0, 0x31,
216 	0xc0, 0x2d, 0xc0, 0x29, 0xc0, 0x25, 0xc0, 0x0e,
217 	0xc0, 0x04, 0x00, 0x9c, 0x00, 0x3c, 0x00, 0x2f,
218 	0x00, 0xba, 0x00, 0x41, 0x00, 0x07, 0xc0, 0x11,
219 	0xc0, 0x07, 0xc0, 0x0c, 0xc0, 0x02, 0x00, 0x05,
220 	0x00, 0x04, 0xc0, 0x12, 0xc0, 0x08, 0x00, 0x16,
221 	0x00, 0x13, 0xc0, 0x0d, 0xc0, 0x03, 0x00, 0x0a,
222 	0x00, 0x15, 0x00, 0x12, 0x00, 0x09, 0x00, 0xff,
223 	0x01, 0x00, 0x00, 0x74, 0x00, 0x0b, 0x00, 0x04,
224 	0x03, 0x00, 0x01, 0x02, 0x00, 0x0a, 0x00, 0x3a,
225 	0x00, 0x38, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x19,
226 	0x00, 0x1c, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1b,
227 	0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x1a,
228 	0x00, 0x16, 0x00, 0x17, 0x00, 0x08, 0x00, 0x06,
229 	0x00, 0x07, 0x00, 0x14, 0x00, 0x15, 0x00, 0x04,
230 	0x00, 0x05, 0x00, 0x12, 0x00, 0x13, 0x00, 0x01,
231 	0x00, 0x02, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10,
232 	0x00, 0x11, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d,
233 	0x00, 0x26, 0x00, 0x24, 0x06, 0x01, 0x06, 0x02,
234 	0x06, 0x03, 0xef, 0xef, 0x05, 0x01, 0x05, 0x02,
235 	0x05, 0x03, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03,
236 	0xee, 0xee, 0xed, 0xed, 0x03, 0x01, 0x03, 0x02,
237 	0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
238 };
239 
240 struct client_hello_test {
241 	const unsigned char *desc;
242 	const int protocol;
243 	const size_t random_start;
244 	const SSL_METHOD *(*ssl_method)(void);
245 	const long ssl_options;
246 };
247 
248 static struct client_hello_test client_hello_tests[] = {
249 	{
250 		.desc = "DTLSv1 client",
251 		.protocol = DTLS1_VERSION,
252 		.random_start = DTLS_RANDOM_OFFSET,
253 		.ssl_method = DTLSv1_client_method,
254 	},
255 	{
256 		.desc = "TLSv1 client",
257 		.protocol = TLS1_VERSION,
258 		.random_start = SSL3_RANDOM_OFFSET,
259 		.ssl_method = TLSv1_client_method,
260 	},
261 	{
262 		.desc = "TLSv1_1 client",
263 		.protocol = TLS1_1_VERSION,
264 		.random_start = SSL3_RANDOM_OFFSET,
265 		.ssl_method = TLSv1_1_client_method,
266 	},
267 	{
268 		.desc = "TLSv1_2 client",
269 		.protocol = TLS1_2_VERSION,
270 		.random_start = SSL3_RANDOM_OFFSET,
271 		.ssl_method = TLSv1_2_client_method,
272 	},
273 	{
274 		.desc = "SSLv23 default",
275 		.protocol = TLS1_2_VERSION,
276 		.random_start = SSL3_RANDOM_OFFSET,
277 		.ssl_method = SSLv23_client_method,
278 		.ssl_options = 0,
279 	},
280 	{
281 		.desc = "SSLv23 (no TLSv1.2)",
282 		.protocol = TLS1_1_VERSION,
283 		.random_start = SSL3_RANDOM_OFFSET,
284 		.ssl_method = SSLv23_client_method,
285 		.ssl_options = SSL_OP_NO_TLSv1_2,
286 	},
287 	{
288 		.desc = "SSLv23 (no TLSv1.1)",
289 		.protocol = TLS1_VERSION,
290 		.random_start = SSL3_RANDOM_OFFSET,
291 		.ssl_method = SSLv23_client_method,
292 		.ssl_options = SSL_OP_NO_TLSv1_1,
293 	},
294 	{
295 		.desc = "TLS default",
296 		.protocol = TLS1_2_VERSION,
297 		.random_start = SSL3_RANDOM_OFFSET,
298 		.ssl_method = TLS_client_method,
299 		.ssl_options = 0,
300 	},
301 	{
302 		.desc = "TLS (no TLSv1.2)",
303 		.protocol = TLS1_1_VERSION,
304 		.random_start = SSL3_RANDOM_OFFSET,
305 		.ssl_method = TLS_client_method,
306 		.ssl_options = SSL_OP_NO_TLSv1_2,
307 	},
308 	{
309 		.desc = "TLS (no TLSv1.1)",
310 		.protocol = TLS1_VERSION,
311 		.random_start = SSL3_RANDOM_OFFSET,
312 		.ssl_method = TLS_client_method,
313 		.ssl_options = SSL_OP_NO_TLSv1_1,
314 	},
315 	{
316 		.desc = "TLS (no TLSv1.0, no TLSv1.1)",
317 		.protocol = TLS1_2_VERSION,
318 		.random_start = SSL3_RANDOM_OFFSET,
319 		.ssl_method = TLS_client_method,
320 		.ssl_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1,
321 	},
322 };
323 
324 #define N_CLIENT_HELLO_TESTS \
325     (sizeof(client_hello_tests) / sizeof(*client_hello_tests))
326 
327 static void
328 hexdump(const unsigned char *buf, size_t len)
329 {
330 	size_t i;
331 
332 	for (i = 1; i <= len; i++)
333 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
334 
335 	fprintf(stderr, "\n");
336 }
337 
338 static inline int
339 ssl_aes_is_accelerated(void)
340 {
341 #if defined(__i386__) || defined(__x86_64__)
342 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
343 #else
344 	return (0);
345 #endif
346 }
347 
348 static int
349 make_client_hello(int protocol, char **out, size_t *outlen)
350 {
351 	size_t client_hello_len, cipher_list_len, cipher_list_offset;
352 	const char *client_hello, *cipher_list;
353 	char *p;
354 
355 	*out = NULL;
356 	*outlen = 0;
357 
358 	switch (protocol) {
359 	case DTLS1_VERSION:
360 		client_hello = client_hello_dtls1;
361 		client_hello_len = sizeof(client_hello_dtls1);
362 		cipher_list = cipher_list_dtls1;
363 		cipher_list_len = sizeof(cipher_list_dtls1);
364 		cipher_list_offset = DTLS_CIPHER_OFFSET;
365 		break;
366 
367 	case TLS1_VERSION:
368 		client_hello = client_hello_tls10;
369 		client_hello_len = sizeof(client_hello_tls10);
370 		cipher_list = cipher_list_tls10;
371 		cipher_list_len = sizeof(cipher_list_tls10);
372 		cipher_list_offset = SSL3_CIPHER_OFFSET;
373 		break;
374 
375 	case TLS1_1_VERSION:
376 		client_hello = client_hello_tls11;
377 		client_hello_len = sizeof(client_hello_tls11);
378 		cipher_list = cipher_list_tls11;
379 		cipher_list_len = sizeof(cipher_list_tls11);
380 		cipher_list_offset = SSL3_CIPHER_OFFSET;
381 		break;
382 
383 	case TLS1_2_VERSION:
384 		client_hello = client_hello_tls12;
385 		client_hello_len = sizeof(client_hello_tls12);
386 		if (ssl_aes_is_accelerated() == 1)
387 			cipher_list = cipher_list_tls12_aes;
388 		else
389 			cipher_list = cipher_list_tls12_chacha;
390 		cipher_list_len = sizeof(cipher_list_tls12_chacha);
391 		cipher_list_offset = SSL3_CIPHER_OFFSET;
392 		break;
393 
394 	default:
395 		return (-1);
396 	}
397 
398 	if ((p = malloc(client_hello_len)) == NULL)
399 		return (-1);
400 
401 	memcpy(p, client_hello, client_hello_len);
402 	memcpy(p + cipher_list_offset, cipher_list, cipher_list_len);
403 
404 	*out = p;
405 	*outlen = client_hello_len;
406 
407 	return (0);
408 }
409 
410 static int
411 client_hello_test(int testno, struct client_hello_test *cht)
412 {
413 	BIO *rbio = NULL, *wbio = NULL;
414 	SSL_CTX *ssl_ctx = NULL;
415 	SSL *ssl = NULL;
416 	char *client_hello = NULL;
417 	size_t client_hello_len;
418 	char *wbuf, rbuf[1];
419 	int ret = 1;
420 	size_t i;
421 	long len;
422 
423 	fprintf(stderr, "Test %i - %s\n", testno, cht->desc);
424 
425 	/* Providing a small buf causes *_get_server_hello() to return. */
426 	if ((rbio = BIO_new_mem_buf(rbuf, sizeof(rbuf))) == NULL) {
427 		fprintf(stderr, "Failed to setup rbio\n");
428 		goto failure;
429 	}
430 	if ((wbio = BIO_new(BIO_s_mem())) == NULL) {
431 		fprintf(stderr, "Failed to setup wbio\n");
432 		goto failure;
433 	}
434 
435 	if ((ssl_ctx = SSL_CTX_new(cht->ssl_method())) == NULL) {
436 		fprintf(stderr, "SSL_CTX_new() returned NULL\n");
437 		goto failure;
438 	}
439 
440 	SSL_CTX_set_options(ssl_ctx, cht->ssl_options);
441 
442 	if ((ssl = SSL_new(ssl_ctx)) == NULL) {
443 		fprintf(stderr, "SSL_new() returned NULL\n");
444 		goto failure;
445 	}
446 
447 	rbio->references = 2;
448 	wbio->references = 2;
449 
450 	SSL_set_bio(ssl, rbio, wbio);
451 
452 	if (SSL_connect(ssl) != 0) {
453 		fprintf(stderr, "SSL_connect() returned non-zero\n");
454 		goto failure;
455 	}
456 
457 	len = BIO_get_mem_data(wbio, &wbuf);
458 
459 	if (make_client_hello(cht->protocol, &client_hello,
460 	    &client_hello_len) != 0)
461 		goto failure;
462 
463 	if ((size_t)len != client_hello_len) {
464 		fprintf(stderr, "FAIL: test returned ClientHello length %li, "
465 		    "want %zu\n", len, client_hello_len);
466 		fprintf(stderr, "received:\n");
467 		hexdump(wbuf, len);
468 		goto failure;
469 	}
470 
471 	/* We expect the client random to differ. */
472 	i = cht->random_start + SSL3_RANDOM_SIZE;
473 	if (memcmp(client_hello, wbuf, cht->random_start) != 0 ||
474 	    memcmp(&client_hello[cht->random_start],
475 		&wbuf[cht->random_start], SSL3_RANDOM_SIZE) == 0 ||
476 	    memcmp(&client_hello[i], &wbuf[i], len - i) != 0) {
477 		fprintf(stderr, "FAIL: ClientHello differs:\n");
478 		fprintf(stderr, "received:\n");
479 		hexdump(wbuf, len);
480 		fprintf(stderr, "test data:\n");
481 		hexdump(client_hello, client_hello_len);
482 		fprintf(stderr, "\n");
483 		goto failure;
484 	}
485 
486 	ret = 0;
487 
488 failure:
489 	SSL_CTX_free(ssl_ctx);
490 	SSL_free(ssl);
491 
492 	rbio->references = 1;
493 	wbio->references = 1;
494 
495 	BIO_free(rbio);
496 	BIO_free(wbio);
497 
498 	free(client_hello);
499 
500 	return (ret);
501 }
502 
503 int
504 main(int argc, char **argv)
505 {
506 	int failed = 0;
507 	size_t i;
508 
509 	SSL_library_init();
510 
511 	for (i = 0; i < N_CLIENT_HELLO_TESTS; i++)
512 		failed |= client_hello_test(i, &client_hello_tests[i]);
513 
514 	return (failed);
515 }
516