blob: 419cce56877d9239ce4adbde813867942ad52fd0 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040026#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040027#include <openssl/err.h>
David Benjaminde942382016-02-11 12:02:01 -050028#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040029#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050031#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032
Steven Valdez87eab492016-06-27 16:34:59 -040033#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040034#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020035#include "../crypto/test/test_util.h"
36
David Benjamin721e8b72016-08-03 13:13:17 -040037#if defined(OPENSSL_WINDOWS)
38/* Windows defines struct timeval in winsock2.h. */
39OPENSSL_MSVC_PRAGMA(warning(push, 3))
40#include <winsock2.h>
41OPENSSL_MSVC_PRAGMA(warning(pop))
42#else
43#include <sys/time.h>
44#endif
45
David Benjamin1d77e562015-03-22 17:22:08 -040046
47struct ExpectedCipher {
48 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040049 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040050};
David Benjaminbb0a17c2014-09-20 15:35:39 -040051
David Benjamin1d77e562015-03-22 17:22:08 -040052struct CipherTest {
53 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050055 // The list of expected ciphers, in order.
56 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040057};
David Benjaminbb0a17c2014-09-20 15:35:39 -040058
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010059struct CurveTest {
60 // The rule string to apply.
61 const char *rule;
62 // The list of expected curves, in order.
63 std::vector<uint16_t> expected;
64};
65
David Benjaminfb974e62015-12-16 19:34:22 -050066static const CipherTest kCipherTests[] = {
67 // Selecting individual ciphers should work.
68 {
69 "ECDHE-ECDSA-CHACHA20-POLY1305:"
70 "ECDHE-RSA-CHACHA20-POLY1305:"
71 "ECDHE-ECDSA-AES128-GCM-SHA256:"
72 "ECDHE-RSA-AES128-GCM-SHA256",
73 {
74 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
75 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
76 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
77 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
78 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
80 },
81 },
82 // + reorders selected ciphers to the end, keeping their relative order.
83 {
84 "ECDHE-ECDSA-CHACHA20-POLY1305:"
85 "ECDHE-RSA-CHACHA20-POLY1305:"
86 "ECDHE-ECDSA-AES128-GCM-SHA256:"
87 "ECDHE-RSA-AES128-GCM-SHA256:"
88 "+aRSA",
89 {
90 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
91 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
92 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
96 },
97 },
98 // ! banishes ciphers from future selections.
99 {
100 "!aRSA:"
101 "ECDHE-ECDSA-CHACHA20-POLY1305:"
102 "ECDHE-RSA-CHACHA20-POLY1305:"
103 "ECDHE-ECDSA-AES128-GCM-SHA256:"
104 "ECDHE-RSA-AES128-GCM-SHA256",
105 {
106 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
107 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
108 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // Multiple masks can be ANDed in a single rule.
112 {
113 "kRSA+AESGCM+AES128",
114 {
115 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
117 },
118 // - removes selected ciphers, but preserves their order for future
119 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
120 // ECDHE_RSA.
121 {
122 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
123 "AESGCM+AES128+aRSA",
124 {
125 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
126 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Unknown selectors are no-ops.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256:"
136 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
139 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
140 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
144 },
145 },
146 // Square brackets specify equi-preference groups.
147 {
148 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
149 "[ECDHE-RSA-CHACHA20-POLY1305]:"
150 "ECDHE-RSA-AES128-GCM-SHA256",
151 {
152 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
153 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
157 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
158 },
159 },
160 // @STRENGTH performs a stable strength-sort of the selected ciphers and
161 // only the selected ciphers.
162 {
163 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700164 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500165 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
166 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500168 // Select ECDHE ones and sort them by strength. Ties should resolve
169 // based on the order above.
170 "kECDHE:@STRENGTH:-ALL:"
171 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
172 // by strength. Then RSA, backwards by strength.
173 "aRSA",
174 {
175 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
176 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
177 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500179 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
180 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
181 },
182 },
183 // Exact ciphers may not be used in multi-part rules; they are treated
184 // as unknown aliases.
185 {
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
189 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
194 },
195 // SSLv3 matches everything that existed before TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
200 },
201 },
202 // TLSv1.2 matches everything added in TLS 1.2.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 },
208 },
209 // The two directives have no intersection.
210 {
211 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
212 {
213 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
214 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
215 },
216 },
217 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
218 // name and not an alias. It may not be used in a multipart rule. (That the
219 // shared name works is covered by the standard tests.)
220 {
221 "ECDHE-ECDSA-CHACHA20-POLY1305:"
222 "ECDHE-RSA-CHACHA20-POLY1305:"
223 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
224 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
225 {
226 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
228 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
229 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
230 },
231 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232};
233
234static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
237 "RSA]",
238 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400244 "",
245 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400246 // COMPLEMENTOFDEFAULT is empty.
247 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400248 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400249 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400250 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400251 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
252 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
253 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700255 // Opcode supplied, but missing selector.
256 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400257};
258
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700259static const char *kMustNotIncludeNull[] = {
260 "ALL",
261 "DEFAULT",
262 "ALL:!eNULL",
263 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500264 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700265 "FIPS",
266 "SHA",
267 "SHA1",
268 "RSA",
269 "SSLv3",
270 "TLSv1",
271 "TLSv1.2",
Steven Valdez3cbdc342016-10-06 14:59:23 -0400272 "GENERIC",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700273};
274
Matt Braithwaite053931e2016-05-25 12:06:05 -0700275static const char *kMustNotIncludeCECPQ1[] = {
276 "ALL",
277 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700278 "HIGH",
279 "FIPS",
280 "SHA",
281 "SHA1",
282 "SHA256",
283 "SHA384",
284 "RSA",
285 "SSLv3",
286 "TLSv1",
287 "TLSv1.2",
288 "aRSA",
289 "RSA",
290 "aECDSA",
291 "ECDSA",
292 "AES",
293 "AES128",
294 "AES256",
295 "AESGCM",
296 "CHACHA20",
Steven Valdez3cbdc342016-10-06 14:59:23 -0400297 "GENERIC",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700298};
299
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100300static const CurveTest kCurveTests[] = {
301 {
302 "P-256",
303 { SSL_CURVE_SECP256R1 },
304 },
305 {
306 "P-256:P-384:P-521:X25519",
307 {
308 SSL_CURVE_SECP256R1,
309 SSL_CURVE_SECP384R1,
310 SSL_CURVE_SECP521R1,
311 SSL_CURVE_X25519,
312 },
313 },
314};
315
316static const char *kBadCurvesLists[] = {
317 "",
318 ":",
319 "::",
320 "P-256::X25519",
321 "RSA:P-256",
322 "P-256:RSA",
323 "X25519:P-256:",
324 ":X25519:P-256",
325};
326
David Benjamin1d77e562015-03-22 17:22:08 -0400327static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
328 bool in_group = false;
329 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
331 if (!in_group && list->in_group_flags[i]) {
332 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400333 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400334 }
335 fprintf(stderr, "\t");
336 if (in_group) {
337 fprintf(stderr, " ");
338 }
339 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
340 if (in_group && !list->in_group_flags[i]) {
341 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400342 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400343 }
344 }
345}
346
David Benjaminfb974e62015-12-16 19:34:22 -0500347static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700348 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400349 if (!ctx) {
350 return false;
David Benjamin65226252015-02-05 16:49:47 -0500351 }
352
David Benjaminfb974e62015-12-16 19:34:22 -0500353 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
354 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400355 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400356 }
357
David Benjamin1d77e562015-03-22 17:22:08 -0400358 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500359 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
360 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
361 PrintCipherPreferenceList(ctx->cipher_list);
362 return false;
363 }
364
365 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400366 const SSL_CIPHER *cipher =
367 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500368 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
369 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
370 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400371 PrintCipherPreferenceList(ctx->cipher_list);
372 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400373 }
374 }
375
David Benjamin1d77e562015-03-22 17:22:08 -0400376 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400377}
378
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700379static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700380 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700381 if (!ctx) {
382 return false;
383 }
384 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
385 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
386 return false;
387 }
388 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
389 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
390 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
391 return false;
392 }
393 }
394 return true;
395}
396
Matt Braithwaite053931e2016-05-25 12:06:05 -0700397static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700398 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700399 if (!ctx) {
400 return false;
401 }
402 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
403 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
404 return false;
405 }
406 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
407 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
408 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
409 return false;
410 }
411 }
412 return true;
413}
414
David Benjamin1d77e562015-03-22 17:22:08 -0400415static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500416 for (const CipherTest &test : kCipherTests) {
417 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400418 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400419 }
420 }
421
David Benjaminfb974e62015-12-16 19:34:22 -0500422 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700423 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400424 if (!ctx) {
425 return false;
David Benjamin65226252015-02-05 16:49:47 -0500426 }
David Benjaminfb974e62015-12-16 19:34:22 -0500427 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
428 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400429 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400430 }
431 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400432 }
433
David Benjaminfb974e62015-12-16 19:34:22 -0500434 for (const char *rule : kMustNotIncludeNull) {
435 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700436 return false;
437 }
438 }
439
Matt Braithwaite053931e2016-05-25 12:06:05 -0700440 for (const char *rule : kMustNotIncludeCECPQ1) {
441 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
442 return false;
443 }
444 }
445
David Benjamin1d77e562015-03-22 17:22:08 -0400446 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447}
David Benjamin2e521212014-07-16 14:37:51 -0400448
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100449static bool TestCurveRule(const CurveTest &t) {
450 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
451 if (!ctx) {
452 return false;
453 }
454
455 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
456 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
457 return false;
458 }
459
460 // Compare the two lists.
461 if (ctx->supported_group_list_len != t.expected.size()) {
462 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
463 return false;
464 }
465
466 for (size_t i = 0; i < t.expected.size(); i++) {
467 if (t.expected[i] != ctx->supported_group_list[i]) {
468 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
469 return false;
470 }
471 }
472
473 return true;
474}
475
476static bool TestCurveRules() {
477 for (const CurveTest &test : kCurveTests) {
478 if (!TestCurveRule(test)) {
479 return false;
480 }
481 }
482
483 for (const char *rule : kBadCurvesLists) {
484 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
485 if (!ctx) {
486 return false;
487 }
488 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
489 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
490 return false;
491 }
492 ERR_clear_error();
493 }
494
495 return true;
496}
497
Adam Langley10f97f32016-07-12 08:09:33 -0700498// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
499// s_client -sess_out.
500static const char kOpenSSLSession[] =
501 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
502 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
503 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
504 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
505 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
506 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
507 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
508 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
509 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
510 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
511 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
512 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
513 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
514 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
515 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
516 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
517 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
518 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
519 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
520 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
521 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
522 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
523 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
524 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
525 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
526 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
527 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
528 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
529 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
530 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
531 "i4gv7Y5oliyn";
532
533// kCustomSession is a custom serialized SSL_SESSION generated by
534// filling in missing fields from |kOpenSSLSession|. This includes
535// providing |peer_sha256|, so |peer| is not serialized.
536static const char kCustomSession[] =
537 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
538 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
539 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
540 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
541 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
542 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
543 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
544 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
545
546// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
547static const char kBoringSSLSession[] =
548 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
549 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
550 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
551 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
552 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
553 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
554 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
555 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
556 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
557 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
558 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
559 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
560 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
561 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
562 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
563 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
564 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
565 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
566 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
567 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
568 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
569 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
570 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
571 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
572 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
573 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
574 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
575 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
576 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
577 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
578 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
579 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
580 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
581 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
582 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
583 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
584 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
585 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
586 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
587 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
588 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
589 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
590 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
591 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
592 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
593 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
594 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
595 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
596 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
597 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
598 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
599 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
600 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
601 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
602 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
603 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
604 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
605 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
606 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
607 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
608 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
609 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
610 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
611 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
612 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
613 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
614 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
615 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
616 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
617 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
618 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
619 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
620 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
621 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
622 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
623 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
624 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
625 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
626 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
627 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
628 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
629 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
630 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
631 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
632 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
633 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
634 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
635 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
636 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
637 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
638 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
639 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
640 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
641 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
642 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
643
644// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
645// the final (optional) element of |kCustomSession| with tag number 30.
646static const char kBadSessionExtraField[] =
647 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
648 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
649 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
650 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
651 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
652 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
653 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
654 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
655
656// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
657// the version of |kCustomSession| with 2.
658static const char kBadSessionVersion[] =
659 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
660 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
661 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
662 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
663 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
664 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
665 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
666 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
667
668// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
669// appended.
670static const char kBadSessionTrailingData[] =
671 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
672 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
673 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
674 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
675 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
676 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
677 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
678 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
679
David Benjamin1d77e562015-03-22 17:22:08 -0400680static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400681 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400682 if (!EVP_DecodedLength(&len, strlen(in))) {
683 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400684 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400685 }
686
David Benjamin1d77e562015-03-22 17:22:08 -0400687 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800688 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400689 strlen(in))) {
690 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400691 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400692 }
David Benjamin1d77e562015-03-22 17:22:08 -0400693 out->resize(len);
694 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400695}
696
David Benjamin1d77e562015-03-22 17:22:08 -0400697static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400698 const uint8_t *cptr;
699 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400700
David Benjamin1d77e562015-03-22 17:22:08 -0400701 // Decode the input.
702 std::vector<uint8_t> input;
703 if (!DecodeBase64(&input, input_b64)) {
704 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400705 }
706
David Benjamin1d77e562015-03-22 17:22:08 -0400707 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700708 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400709 if (!session) {
710 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400711 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400712 }
713
David Benjamin1d77e562015-03-22 17:22:08 -0400714 // Verify the SSL_SESSION encoding round-trips.
715 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700716 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400717 uint8_t *encoded_raw;
718 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400719 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400720 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400721 }
David Benjamin1d77e562015-03-22 17:22:08 -0400722 encoded.reset(encoded_raw);
723 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800724 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400725 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200726 hexdump(stderr, "Before: ", input.data(), input.size());
727 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400728 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400729 }
David Benjamin3cac4502014-10-21 01:46:30 -0400730
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800732 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400733 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800734 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400735 fprintf(stderr, "d2i_SSL_SESSION failed\n");
736 return false;
737 }
738
David Benjamin1d77e562015-03-22 17:22:08 -0400739 // Verify the SSL_SESSION encoding round-trips via the legacy API.
740 int len = i2d_SSL_SESSION(session.get(), NULL);
741 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400742 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400743 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400744 }
745
David Benjamin1d77e562015-03-22 17:22:08 -0400746 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
747 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400748 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400749 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400750 }
David Benjamin1d77e562015-03-22 17:22:08 -0400751
752 ptr = encoded.get();
753 len = i2d_SSL_SESSION(session.get(), &ptr);
754 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400755 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400756 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400757 }
David Benjamin1d77e562015-03-22 17:22:08 -0400758 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400759 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400760 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400761 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800762 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400763 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400764 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400765 }
766
David Benjamin1d77e562015-03-22 17:22:08 -0400767 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400768}
769
David Benjaminf297e022015-05-28 19:55:29 -0400770static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
771 std::vector<uint8_t> input;
772 if (!DecodeBase64(&input, input_b64)) {
773 return false;
774 }
775
776 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700777 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400778 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400779 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400780 return false;
781 }
782 ERR_clear_error();
783 return true;
784}
785
David Benjamin10e664b2016-06-20 22:20:47 -0400786static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400787 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700788 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400789 if (!ctx) {
790 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500791 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400792 if (ctx->min_version != min_version || ctx->max_version != max_version) {
793 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
794 ctx->min_version, ctx->max_version, min_version, max_version);
795 return false;
796 }
797 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500798}
799
David Benjamin1d77e562015-03-22 17:22:08 -0400800static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500801 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
802 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400803 return false;
David Benjamin65226252015-02-05 16:49:47 -0500804 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700805 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400806 if (!rfc_name) {
807 return false;
808 }
David Benjamin67be0482015-04-20 16:19:00 -0400809 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400810 return true;
David Benjamin65226252015-02-05 16:49:47 -0500811}
812
813typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500814 int id;
David Benjamin65226252015-02-05 16:49:47 -0500815 const char *rfc_name;
816} CIPHER_RFC_NAME_TEST;
817
818static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400819 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
820 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
821 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
822 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
823 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
824 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
825 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
826 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
827 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
828 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
829 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
830 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
831 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
832 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
833 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
834 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
835 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
836 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
837 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
838 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
839 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
840 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
841
842 // These names are non-standard:
843 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
844 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
845 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
846 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500847};
848
David Benjamin1d77e562015-03-22 17:22:08 -0400849static bool TestCipherGetRFCName(void) {
850 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400851 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500852 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400853 std::string rfc_name;
854 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
855 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
856 return false;
David Benjamin65226252015-02-05 16:49:47 -0500857 }
David Benjamin1d77e562015-03-22 17:22:08 -0400858 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500859 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400860 rfc_name.c_str(), test->rfc_name);
861 return false;
David Benjamin65226252015-02-05 16:49:47 -0500862 }
David Benjamin65226252015-02-05 16:49:47 -0500863 }
David Benjamin1d77e562015-03-22 17:22:08 -0400864 return true;
David Benjamin65226252015-02-05 16:49:47 -0500865}
866
David Benjamin422fe082015-07-21 22:03:43 -0400867// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
868// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700869static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400870 std::vector<uint8_t> der;
871 if (!DecodeBase64(&der, kOpenSSLSession)) {
872 return nullptr;
873 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700874 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400875 if (!session) {
876 return nullptr;
877 }
878
879 // Swap out the ticket for a garbage one.
880 OPENSSL_free(session->tlsext_tick);
881 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
882 if (session->tlsext_tick == nullptr) {
883 return nullptr;
884 }
885 memset(session->tlsext_tick, 'a', ticket_len);
886 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400887
888 // Fix up the timeout.
889 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400890 return session;
891}
892
David Benjaminafc64de2016-07-19 17:12:41 +0200893static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700894 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200895 if (!bio) {
896 return false;
897 }
898 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400899 BIO_up_ref(bio.get());
900 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200901 int ret = SSL_connect(ssl);
902 if (ret > 0) {
903 // SSL_connect should fail without a BIO to write to.
904 return false;
905 }
906 ERR_clear_error();
907
908 const uint8_t *client_hello;
909 size_t client_hello_len;
910 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
911 return false;
912 }
913 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
914 return true;
915}
916
David Benjamin422fe082015-07-21 22:03:43 -0400917// GetClientHelloLen creates a client SSL connection with a ticket of length
918// |ticket_len| and records the ClientHello. It returns the length of the
919// ClientHello, not including the record header, on success and zero on error.
920static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700921 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
922 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400923 if (!ctx || !session) {
924 return 0;
925 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700926 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200927 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400928 return 0;
929 }
David Benjaminafc64de2016-07-19 17:12:41 +0200930 std::vector<uint8_t> client_hello;
931 if (!GetClientHello(ssl.get(), &client_hello) ||
932 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400933 return 0;
934 }
David Benjaminafc64de2016-07-19 17:12:41 +0200935 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400936}
937
938struct PaddingTest {
939 size_t input_len, padded_len;
940};
941
942static const PaddingTest kPaddingTests[] = {
943 // ClientHellos of length below 0x100 do not require padding.
944 {0xfe, 0xfe},
945 {0xff, 0xff},
946 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
947 {0x100, 0x200},
948 {0x123, 0x200},
949 {0x1fb, 0x200},
950 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
951 // padding extension takes a minimum of four bytes plus one required content
952 // byte. (To work around yet more server bugs, we avoid empty final
953 // extensions.)
954 {0x1fc, 0x201},
955 {0x1fd, 0x202},
956 {0x1fe, 0x203},
957 {0x1ff, 0x204},
958 // Finally, larger ClientHellos need no padding.
959 {0x200, 0x200},
960 {0x201, 0x201},
961};
962
963static bool TestPaddingExtension() {
964 // Sample a baseline length.
965 size_t base_len = GetClientHelloLen(1);
966 if (base_len == 0) {
967 return false;
968 }
969
970 for (const PaddingTest &test : kPaddingTests) {
971 if (base_len > test.input_len) {
972 fprintf(stderr, "Baseline ClientHello too long.\n");
973 return false;
974 }
975
976 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
977 if (padded_len != test.padded_len) {
978 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
979 static_cast<unsigned>(test.input_len),
980 static_cast<unsigned>(padded_len),
981 static_cast<unsigned>(test.padded_len));
982 return false;
983 }
984 }
985 return true;
986}
987
David Benjamin1d128f32015-09-08 17:41:40 -0400988// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
989// before configuring as a server.
990static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700991 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400992 if (!ctx) {
993 return false;
994 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700995 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400996 if (!ssl) {
997 return false;
998 }
999
1000 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
1001 if (stack == nullptr) {
1002 return false;
1003 }
1004 // |SSL_set_client_CA_list| takes ownership.
1005 SSL_set_client_CA_list(ssl.get(), stack);
1006
1007 return SSL_get_client_CA_list(ssl.get()) == stack;
1008}
1009
David Benjamin0f653952015-10-18 14:28:01 -04001010static void AppendSession(SSL_SESSION *session, void *arg) {
1011 std::vector<SSL_SESSION*> *out =
1012 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1013 out->push_back(session);
1014}
1015
1016// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1017// order.
1018static bool ExpectCache(SSL_CTX *ctx,
1019 const std::vector<SSL_SESSION*> &expected) {
1020 // Check the linked list.
1021 SSL_SESSION *ptr = ctx->session_cache_head;
1022 for (SSL_SESSION *session : expected) {
1023 if (ptr != session) {
1024 return false;
1025 }
1026 // TODO(davidben): This is an absurd way to denote the end of the list.
1027 if (ptr->next ==
1028 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1029 ptr = nullptr;
1030 } else {
1031 ptr = ptr->next;
1032 }
1033 }
1034 if (ptr != nullptr) {
1035 return false;
1036 }
1037
1038 // Check the hash table.
1039 std::vector<SSL_SESSION*> actual, expected_copy;
1040 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1041 expected_copy = expected;
1042
1043 std::sort(actual.begin(), actual.end());
1044 std::sort(expected_copy.begin(), expected_copy.end());
1045
1046 return actual == expected_copy;
1047}
1048
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001049static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1050 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001051 if (!ret) {
1052 return nullptr;
1053 }
1054
1055 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1056 memset(ret->session_id, 0, ret->session_id_length);
1057 memcpy(ret->session_id, &number, sizeof(number));
1058 return ret;
1059}
1060
David Benjamin0f653952015-10-18 14:28:01 -04001061// Test that the internal session cache behaves as expected.
1062static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001063 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001064 if (!ctx) {
1065 return false;
1066 }
1067
1068 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001069 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001070 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001071 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001072 if (!session) {
1073 return false;
1074 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001075 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001076 }
1077
1078 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1079
1080 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001081 for (const auto &session : sessions) {
1082 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001083 return false;
1084 }
1085 }
1086
1087 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001088 std::vector<SSL_SESSION*> expected = {
1089 sessions[9].get(),
1090 sessions[8].get(),
1091 sessions[7].get(),
1092 sessions[6].get(),
1093 sessions[5].get(),
1094 };
David Benjamin0f653952015-10-18 14:28:01 -04001095 if (!ExpectCache(ctx.get(), expected)) {
1096 return false;
1097 }
1098
1099 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001100 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001101 !ExpectCache(ctx.get(), expected)) {
1102 return false;
1103 }
1104
1105 // Although collisions should be impossible (256-bit session IDs), the cache
1106 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001107 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001108 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1109 return false;
1110 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001111 expected = {
1112 collision.get(),
1113 sessions[9].get(),
1114 sessions[8].get(),
1115 sessions[6].get(),
1116 sessions[5].get(),
1117 };
David Benjamin0f653952015-10-18 14:28:01 -04001118 if (!ExpectCache(ctx.get(), expected)) {
1119 return false;
1120 }
1121
1122 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001123 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001124 return false;
1125 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001126 expected = {
1127 collision.get(),
1128 sessions[9].get(),
1129 sessions[8].get(),
1130 sessions[5].get(),
1131 };
David Benjamin0f653952015-10-18 14:28:01 -04001132 if (!ExpectCache(ctx.get(), expected)) {
1133 return false;
1134 }
1135
1136 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001137 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1138 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001139 !ExpectCache(ctx.get(), expected)) {
1140 return false;
1141 }
1142
1143 return true;
1144}
1145
David Benjaminde942382016-02-11 12:02:01 -05001146static uint16_t EpochFromSequence(uint64_t seq) {
1147 return static_cast<uint16_t>(seq >> 48);
1148}
1149
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001150static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001151 static const char kCertPEM[] =
1152 "-----BEGIN CERTIFICATE-----\n"
1153 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1154 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1155 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1156 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1157 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1158 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1159 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1160 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1161 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1162 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1163 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1164 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1165 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1166 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1168 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001169}
1170
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001171static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001172 static const char kKeyPEM[] =
1173 "-----BEGIN RSA PRIVATE KEY-----\n"
1174 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1175 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1176 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1177 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1178 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1179 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1180 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1181 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1182 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1183 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1184 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1185 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1186 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1187 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001188 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1189 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001190 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1191}
1192
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001193static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001194 static const char kCertPEM[] =
1195 "-----BEGIN CERTIFICATE-----\n"
1196 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1197 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1198 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1199 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1200 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1201 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1202 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1203 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1204 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1205 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1206 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001207 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1208 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001209}
1210
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001211static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001212 static const char kKeyPEM[] =
1213 "-----BEGIN PRIVATE KEY-----\n"
1214 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1215 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1216 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1217 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001218 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1219 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001220 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1221}
1222
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001223static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001224 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1225 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001226 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001227 if (!client || !server) {
1228 return false;
1229 }
1230 SSL_set_connect_state(client.get());
1231 SSL_set_accept_state(server.get());
1232
David Benjamina20e5352016-08-02 19:09:41 -04001233 SSL_set_session(client.get(), session);
1234
David Benjaminde942382016-02-11 12:02:01 -05001235 BIO *bio1, *bio2;
1236 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1237 return false;
1238 }
1239 // SSL_set_bio takes ownership.
1240 SSL_set_bio(client.get(), bio1, bio1);
1241 SSL_set_bio(server.get(), bio2, bio2);
1242
1243 // Drive both their handshakes to completion.
1244 for (;;) {
1245 int client_ret = SSL_do_handshake(client.get());
1246 int client_err = SSL_get_error(client.get(), client_ret);
1247 if (client_err != SSL_ERROR_NONE &&
1248 client_err != SSL_ERROR_WANT_READ &&
1249 client_err != SSL_ERROR_WANT_WRITE) {
1250 fprintf(stderr, "Client error: %d\n", client_err);
1251 return false;
1252 }
1253
1254 int server_ret = SSL_do_handshake(server.get());
1255 int server_err = SSL_get_error(server.get(), server_ret);
1256 if (server_err != SSL_ERROR_NONE &&
1257 server_err != SSL_ERROR_WANT_READ &&
1258 server_err != SSL_ERROR_WANT_WRITE) {
1259 fprintf(stderr, "Server error: %d\n", server_err);
1260 return false;
1261 }
1262
1263 if (client_ret == 1 && server_ret == 1) {
1264 break;
1265 }
1266 }
1267
David Benjamin686bb192016-05-10 15:15:41 -04001268 *out_client = std::move(client);
1269 *out_server = std::move(server);
1270 return true;
1271}
1272
1273static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001274 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1275 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001276 if (!client_ctx || !server_ctx) {
1277 return false;
1278 }
1279
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001280 bssl::UniquePtr<X509> cert = GetTestCertificate();
1281 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001282 if (!cert || !key ||
1283 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1284 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1285 return false;
1286 }
1287
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001288 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001289 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001290 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001291 return false;
1292 }
1293
David Benjaminde942382016-02-11 12:02:01 -05001294 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1295 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1296 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1297 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1298
1299 if (dtls) {
1300 // Both client and server must be at epoch 1.
1301 if (EpochFromSequence(client_read_seq) != 1 ||
1302 EpochFromSequence(client_write_seq) != 1 ||
1303 EpochFromSequence(server_read_seq) != 1 ||
1304 EpochFromSequence(server_write_seq) != 1) {
1305 fprintf(stderr, "Bad epochs.\n");
1306 return false;
1307 }
1308
1309 // The next record to be written should exceed the largest received.
1310 if (client_write_seq <= server_read_seq ||
1311 server_write_seq <= client_read_seq) {
1312 fprintf(stderr, "Inconsistent sequence numbers.\n");
1313 return false;
1314 }
1315 } else {
1316 // The next record to be written should equal the next to be received.
1317 if (client_write_seq != server_read_seq ||
1318 server_write_seq != client_write_seq) {
1319 fprintf(stderr, "Inconsistent sequence numbers.\n");
1320 return false;
1321 }
1322 }
1323
1324 // Send a record from client to server.
1325 uint8_t byte = 0;
1326 if (SSL_write(client.get(), &byte, 1) != 1 ||
1327 SSL_read(server.get(), &byte, 1) != 1) {
1328 fprintf(stderr, "Could not send byte.\n");
1329 return false;
1330 }
1331
1332 // The client write and server read sequence numbers should have incremented.
1333 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1334 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1335 fprintf(stderr, "Sequence numbers did not increment.\n");\
1336 return false;
1337 }
1338
1339 return true;
1340}
1341
David Benjamin686bb192016-05-10 15:15:41 -04001342static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001343 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1344 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001345 if (!client_ctx || !server_ctx) {
1346 return false;
1347 }
1348
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001349 bssl::UniquePtr<X509> cert = GetTestCertificate();
1350 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001351 if (!cert || !key ||
1352 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1353 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1354 return false;
1355 }
1356
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001357 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001358 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001359 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001360 return false;
1361 }
1362
1363 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1364 // one side has shut down.
1365 if (SSL_shutdown(client.get()) != 0) {
1366 fprintf(stderr, "Could not shutdown.\n");
1367 return false;
1368 }
1369
1370 // Reading from the server should consume the EOF.
1371 uint8_t byte;
1372 if (SSL_read(server.get(), &byte, 1) != 0 ||
1373 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1374 fprintf(stderr, "Connection was not shut down cleanly.\n");
1375 return false;
1376 }
1377
1378 // However, the server may continue to write data and then shut down the
1379 // connection.
1380 byte = 42;
1381 if (SSL_write(server.get(), &byte, 1) != 1 ||
1382 SSL_read(client.get(), &byte, 1) != 1 ||
1383 byte != 42) {
1384 fprintf(stderr, "Could not send byte.\n");
1385 return false;
1386 }
1387
1388 // The server may then shutdown the connection.
1389 if (SSL_shutdown(server.get()) != 1 ||
1390 SSL_shutdown(client.get()) != 1) {
1391 fprintf(stderr, "Could not complete shutdown.\n");
1392 return false;
1393 }
1394
1395 return true;
1396}
Steven Valdez87eab492016-06-27 16:34:59 -04001397static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001398 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1399 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001400 if (!client_ctx || !server_ctx) {
1401 return false;
1402 }
1403
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001404 bssl::UniquePtr<X509> cert = GetTestCertificate();
1405 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001406 if (!cert || !key ||
1407 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1408 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1409 return false;
1410 }
1411
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001412 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001413 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001414 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001415 return false;
1416 }
1417
1418 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001419 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001420 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001421 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001422 }
David Benjamin4501bd52016-08-01 13:39:41 -04001423
Steven Valdez84b5c002016-08-25 16:30:58 -04001424 session1->not_resumable = 0;
1425
Steven Valdez87eab492016-06-27 16:34:59 -04001426 uint8_t *s0_bytes, *s1_bytes;
1427 size_t s0_len, s1_len;
1428
1429 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1430 return false;
1431 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001432 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001433
1434 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1435 return false;
1436 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001437 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001438
1439 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1440}
David Benjamin686bb192016-05-10 15:15:41 -04001441
David Benjamin5c0fb882016-06-14 14:03:51 -04001442static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1443 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1444 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1445 SSL_get_wfd(ssl), rfd, wfd);
1446 return false;
1447 }
1448
1449 // The wrapper BIOs are always equal when fds are equal, even if set
1450 // individually.
1451 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1452 fprintf(stderr, "rbio and wbio did not match.\n");
1453 return false;
1454 }
1455
1456 return true;
1457}
1458
1459static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001460 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001461 if (!ctx) {
1462 return false;
1463 }
1464
1465 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001466 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001467 if (!ssl ||
1468 !SSL_set_rfd(ssl.get(), 1) ||
1469 !SSL_set_wfd(ssl.get(), 2) ||
1470 !ExpectFDs(ssl.get(), 1, 2)) {
1471 return false;
1472 }
1473
1474 // Test setting the same FD.
1475 ssl.reset(SSL_new(ctx.get()));
1476 if (!ssl ||
1477 !SSL_set_fd(ssl.get(), 1) ||
1478 !ExpectFDs(ssl.get(), 1, 1)) {
1479 return false;
1480 }
1481
1482 // Test setting the same FD one side at a time.
1483 ssl.reset(SSL_new(ctx.get()));
1484 if (!ssl ||
1485 !SSL_set_rfd(ssl.get(), 1) ||
1486 !SSL_set_wfd(ssl.get(), 1) ||
1487 !ExpectFDs(ssl.get(), 1, 1)) {
1488 return false;
1489 }
1490
1491 // Test setting the same FD in the other order.
1492 ssl.reset(SSL_new(ctx.get()));
1493 if (!ssl ||
1494 !SSL_set_wfd(ssl.get(), 1) ||
1495 !SSL_set_rfd(ssl.get(), 1) ||
1496 !ExpectFDs(ssl.get(), 1, 1)) {
1497 return false;
1498 }
1499
David Benjamin5c0fb882016-06-14 14:03:51 -04001500 // Test changing the read FD partway through.
1501 ssl.reset(SSL_new(ctx.get()));
1502 if (!ssl ||
1503 !SSL_set_fd(ssl.get(), 1) ||
1504 !SSL_set_rfd(ssl.get(), 2) ||
1505 !ExpectFDs(ssl.get(), 2, 1)) {
1506 return false;
1507 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001508
1509 // Test changing the write FD partway through.
1510 ssl.reset(SSL_new(ctx.get()));
1511 if (!ssl ||
1512 !SSL_set_fd(ssl.get(), 1) ||
1513 !SSL_set_wfd(ssl.get(), 2) ||
1514 !ExpectFDs(ssl.get(), 1, 2)) {
1515 return false;
1516 }
1517
1518 // Test a no-op change to the read FD partway through.
1519 ssl.reset(SSL_new(ctx.get()));
1520 if (!ssl ||
1521 !SSL_set_fd(ssl.get(), 1) ||
1522 !SSL_set_rfd(ssl.get(), 1) ||
1523 !ExpectFDs(ssl.get(), 1, 1)) {
1524 return false;
1525 }
1526
1527 // Test a no-op change to the write FD partway through.
1528 ssl.reset(SSL_new(ctx.get()));
1529 if (!ssl ||
1530 !SSL_set_fd(ssl.get(), 1) ||
1531 !SSL_set_wfd(ssl.get(), 1) ||
1532 !ExpectFDs(ssl.get(), 1, 1)) {
1533 return false;
1534 }
1535
1536 // ASan builds will implicitly test that the internal |BIO| reference-counting
1537 // is correct.
1538
1539 return true;
1540}
1541
David Benjamin4501bd52016-08-01 13:39:41 -04001542static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001543 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001544 if (!ctx) {
1545 return false;
1546 }
1547
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001548 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1549 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001550 bio3(BIO_new(BIO_s_mem()));
1551 if (!ssl || !bio1 || !bio2 || !bio3) {
1552 return false;
1553 }
1554
1555 // SSL_set_bio takes one reference when the parameters are the same.
1556 BIO_up_ref(bio1.get());
1557 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1558
1559 // Repeating the call does nothing.
1560 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1561
1562 // It takes one reference each when the parameters are different.
1563 BIO_up_ref(bio2.get());
1564 BIO_up_ref(bio3.get());
1565 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1566
1567 // Repeating the call does nothing.
1568 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1569
1570 // It takes one reference when changing only wbio.
1571 BIO_up_ref(bio1.get());
1572 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1573
1574 // It takes one reference when changing only rbio and the two are different.
1575 BIO_up_ref(bio3.get());
1576 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1577
1578 // If setting wbio to rbio, it takes no additional references.
1579 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1580
1581 // From there, wbio may be switched to something else.
1582 BIO_up_ref(bio1.get());
1583 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1584
1585 // If setting rbio to wbio, it takes no additional references.
1586 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1587
1588 // From there, rbio may be switched to something else, but, for historical
1589 // reasons, it takes a reference to both parameters.
1590 BIO_up_ref(bio1.get());
1591 BIO_up_ref(bio2.get());
1592 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1593
1594 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1595 // is correct.
1596 return true;
1597}
1598
David Benjamincb18ac22016-09-27 14:09:15 -04001599static uint16_t kTLSVersions[] = {
David Benjamin25490f22016-07-14 00:22:54 -04001600 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1601};
1602
David Benjamincb18ac22016-09-27 14:09:15 -04001603static uint16_t kDTLSVersions[] = {
1604 DTLS1_VERSION, DTLS1_2_VERSION,
1605};
1606
David Benjamin25490f22016-07-14 00:22:54 -04001607static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1608
David Benjaminadd5e522016-07-14 00:33:24 -04001609static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001610 bssl::UniquePtr<X509> cert = GetTestCertificate();
1611 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001612 if (!cert || !key) {
1613 return false;
1614 }
1615
David Benjamincb18ac22016-09-27 14:09:15 -04001616 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001617 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001618 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001619 if (!ctx ||
1620 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001621 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001622 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1623 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001624 return false;
1625 }
David Benjaminadd5e522016-07-14 00:33:24 -04001626 SSL_CTX_set_verify(
1627 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1628 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1629
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001630 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001631 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1632 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001633 return false;
1634 }
1635
1636 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001637 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001638 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1639 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1640 return false;
1641 }
1642
1643 peer.reset(SSL_get_peer_certificate(client.get()));
1644 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1645 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1646 return false;
1647 }
1648
1649 // However, for historical reasons, the chain includes the leaf on the
1650 // client, but does not on the server.
1651 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1652 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1653 return false;
1654 }
1655
1656 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1657 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1658 return false;
1659 }
1660 }
1661
1662 return true;
1663}
1664
David Benjamin25490f22016-07-14 00:22:54 -04001665static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001666 bssl::UniquePtr<X509> cert = GetTestCertificate();
1667 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001668 if (!cert || !key) {
1669 return false;
1670 }
1671
1672 uint8_t *cert_der = NULL;
1673 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1674 if (cert_der_len < 0) {
1675 return false;
1676 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001677 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001678
1679 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1680 SHA256(cert_der, cert_der_len, cert_sha256);
1681
David Benjamincb18ac22016-09-27 14:09:15 -04001682 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001683 // Configure both client and server to accept any certificate, but the
1684 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001685 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001686 if (!ctx ||
1687 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001688 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001689 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1690 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001691 return false;
1692 }
David Benjamin25490f22016-07-14 00:22:54 -04001693 SSL_CTX_set_verify(
1694 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1695 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1696 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1697
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001698 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001699 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1700 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001701 return false;
1702 }
1703
1704 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001705 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001706 if (peer) {
1707 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1708 return false;
1709 }
1710
1711 SSL_SESSION *session = SSL_get_session(server.get());
1712 if (!session->peer_sha256_valid) {
1713 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1714 return false;
1715 }
1716
1717 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1718 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1719 return false;
1720 }
1721 }
1722
1723 return true;
1724}
1725
David Benjaminafc64de2016-07-19 17:12:41 +02001726static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1727 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001728 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001729 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001730 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001731 // Our default cipher list varies by CPU capabilities, so manually place
1732 // the ChaCha20 ciphers in front.
1733 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001734 return false;
1735 }
David Benjamin2dc02042016-09-19 19:57:37 -04001736
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001737 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001738 if (!ssl) {
1739 return false;
1740 }
1741 std::vector<uint8_t> client_hello;
1742 if (!GetClientHello(ssl.get(), &client_hello)) {
1743 return false;
1744 }
1745
1746 // Zero the client_random.
1747 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1748 1 + 3 + // handshake message header
1749 2; // client_version
1750 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1751 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1752 return false;
1753 }
1754 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1755
1756 if (client_hello.size() != expected_len ||
1757 memcmp(client_hello.data(), expected, expected_len) != 0) {
1758 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1759 fprintf(stderr, "Got:\n\t");
1760 for (size_t i = 0; i < client_hello.size(); i++) {
1761 fprintf(stderr, "0x%02x, ", client_hello[i]);
1762 }
1763 fprintf(stderr, "\nWanted:\n\t");
1764 for (size_t i = 0; i < expected_len; i++) {
1765 fprintf(stderr, "0x%02x, ", expected[i]);
1766 }
1767 fprintf(stderr, "\n");
1768 return false;
1769 }
1770
1771 return true;
1772}
1773
1774// Tests that our ClientHellos do not change unexpectedly.
1775static bool TestClientHello() {
1776 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001777 0x16,
1778 0x03, 0x00,
1779 0x00, 0x3f,
1780 0x01,
1781 0x00, 0x00, 0x3b,
1782 0x03, 0x00,
1783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1787 0x00,
1788 0x00, 0x14,
1789 0xc0, 0x09,
1790 0xc0, 0x13,
1791 0x00, 0x33,
1792 0xc0, 0x0a,
1793 0xc0, 0x14,
1794 0x00, 0x39,
1795 0x00, 0x2f,
1796 0x00, 0x35,
1797 0x00, 0x0a,
1798 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001799 };
1800 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1801 sizeof(kSSL3ClientHello))) {
1802 return false;
1803 }
1804
1805 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001806 0x16,
1807 0x03, 0x01,
1808 0x00, 0x5e,
1809 0x01,
1810 0x00, 0x00, 0x5a,
1811 0x03, 0x01,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1816 0x00,
1817 0x00, 0x12,
1818 0xc0, 0x09,
1819 0xc0, 0x13,
1820 0x00, 0x33,
1821 0xc0, 0x0a,
1822 0xc0, 0x14,
1823 0x00, 0x39,
1824 0x00, 0x2f,
1825 0x00, 0x35,
1826 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001827 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1828 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1829 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1830 };
1831 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1832 sizeof(kTLS1ClientHello))) {
1833 return false;
1834 }
1835
1836 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001837 0x16,
1838 0x03, 0x01,
1839 0x00, 0x5e,
1840 0x01,
1841 0x00, 0x00, 0x5a,
1842 0x03, 0x02,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1847 0x00,
1848 0x00, 0x12,
1849 0xc0, 0x09,
1850 0xc0, 0x13,
1851 0x00, 0x33,
1852 0xc0, 0x0a,
1853 0xc0, 0x14,
1854 0x00, 0x39,
1855 0x00, 0x2f,
1856 0x00, 0x35,
1857 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001858 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1859 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1860 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1861 };
1862 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1863 sizeof(kTLS11ClientHello))) {
1864 return false;
1865 }
1866
1867 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001868 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1872 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1873 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1874 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1875 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1876 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1877 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjaminaf56fbd2016-09-21 14:38:06 -04001878 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
1879 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
David Benjamin57e929f2016-08-30 00:30:38 -04001880 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1881 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001882 };
1883 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1884 sizeof(kTLS12ClientHello))) {
1885 return false;
1886 }
1887
1888 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1889 // implementation has settled enough that it won't change.
1890
1891 return true;
1892}
1893
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001894static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001895
1896static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1897 // Save the most recent session.
1898 g_last_session.reset(session);
1899 return 1;
1900}
1901
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001902static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001903 SSL_CTX *server_ctx) {
1904 g_last_session = nullptr;
1905 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1906
1907 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001908 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001909 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1910 nullptr /* no session */)) {
1911 fprintf(stderr, "Failed to connect client and server.\n");
1912 return nullptr;
1913 }
1914
1915 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1916 SSL_read(client.get(), nullptr, 0);
1917
1918 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1919
1920 if (!g_last_session) {
1921 fprintf(stderr, "Client did not receive a session.\n");
1922 return nullptr;
1923 }
1924 return std::move(g_last_session);
1925}
1926
1927static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1928 SSL_SESSION *session,
1929 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001930 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001931 if (!ConnectClientAndServer(&client, &server, client_ctx,
1932 server_ctx, session)) {
1933 fprintf(stderr, "Failed to connect client and server.\n");
1934 return false;
1935 }
1936
1937 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1938 fprintf(stderr, "Client and server were inconsistent.\n");
1939 return false;
1940 }
1941
1942 bool was_reused = !!SSL_session_reused(client.get());
1943 if (was_reused != reused) {
1944 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1945 was_reused ? "" : " not");
1946 return false;
1947 }
1948
1949 return true;
1950}
1951
1952static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001953 bssl::UniquePtr<X509> cert = GetTestCertificate();
1954 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001955 if (!cert || !key) {
1956 return false;
1957 }
1958
1959 static const uint8_t kContext1[] = {1};
1960 static const uint8_t kContext2[] = {2};
1961
David Benjamincb18ac22016-09-27 14:09:15 -04001962 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001963 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1964 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001965 if (!server_ctx || !client_ctx ||
1966 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1967 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1968 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001969 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001970 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1971 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1972 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1973 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001974 return false;
1975 }
1976
David Benjamina20e5352016-08-02 19:09:41 -04001977 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04001978 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1979
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001980 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001981 CreateClientSession(client_ctx.get(), server_ctx.get());
1982 if (!session) {
1983 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1984 return false;
1985 }
1986
1987 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1988 true /* expect session reused */)) {
1989 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1990 return false;
1991 }
1992
1993 // Change the session ID context.
1994 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1995 sizeof(kContext2))) {
1996 return false;
1997 }
1998
1999 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2000 false /* expect session not reused */)) {
2001 fprintf(stderr,
2002 "Error connection with different context (version = %04x).\n",
2003 version);
2004 return false;
2005 }
2006 }
2007
2008 return true;
2009}
2010
David Benjamin721e8b72016-08-03 13:13:17 -04002011static timeval g_current_time;
2012
2013static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2014 *out_clock = g_current_time;
2015}
2016
2017static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002018 bssl::UniquePtr<X509> cert = GetTestCertificate();
2019 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002020 if (!cert || !key) {
2021 return false;
2022 }
2023
David Benjamincb18ac22016-09-27 14:09:15 -04002024 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002025 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2026 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04002027 if (!server_ctx || !client_ctx ||
2028 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002029 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002030 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2031 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2032 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2033 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamin721e8b72016-08-03 13:13:17 -04002034 return false;
2035 }
2036
David Benjamin721e8b72016-08-03 13:13:17 -04002037 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2038
David Benjamin721e8b72016-08-03 13:13:17 -04002039 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2040 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2041
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002042 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04002043 CreateClientSession(client_ctx.get(), server_ctx.get());
2044 if (!session) {
2045 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2046 return false;
2047 }
2048
2049 // Advance the clock just behind the timeout.
2050 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
2051
2052 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2053 true /* expect session reused */)) {
2054 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2055 return false;
2056 }
2057
2058 // Advance the clock one more second.
2059 g_current_time.tv_sec++;
2060
2061 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2062 false /* expect session not reused */)) {
2063 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2064 return false;
2065 }
2066 }
2067
2068 return true;
2069}
2070
David Benjamin0fc37ef2016-08-17 15:29:46 -04002071static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2072 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2073 SSL_set_SSL_CTX(ssl, ctx);
2074 return SSL_TLSEXT_ERR_OK;
2075}
2076
2077static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002078 bssl::UniquePtr<X509> cert = GetTestCertificate();
2079 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2080 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2081 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002082 if (!cert || !key || !cert2 || !key2) {
2083 return false;
2084 }
2085
2086 // At each version, test that switching the |SSL_CTX| at the SNI callback
2087 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002088 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002089 if (version == SSL3_VERSION) {
2090 continue;
2091 }
2092
2093 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2094
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002095 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2096 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2097 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002098 if (!server_ctx || !server_ctx2 || !client_ctx ||
2099 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2100 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2101 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2102 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2103 // Historically signing preferences would be lost in some cases with the
2104 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2105 // this doesn't happen when |version| is TLS 1.2, configure the private
2106 // key to only sign SHA-256.
2107 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002108 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002109 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2110 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2111 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2112 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2113 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2114 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002115 return false;
2116 }
2117
David Benjamin0fc37ef2016-08-17 15:29:46 -04002118 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2119 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2120
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002121 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002122 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2123 server_ctx.get(), nullptr)) {
2124 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2125 return false;
2126 }
2127
2128 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002129 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002130 if (!peer ||
2131 X509_cmp(peer.get(), cert2.get()) != 0) {
2132 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2133 version);
2134 return false;
2135 }
2136 }
2137
2138 return true;
2139}
2140
David Benjamin99620572016-08-30 00:35:36 -04002141static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002142 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002143 return -1;
2144 }
2145
David Benjamin99620572016-08-30 00:35:36 -04002146 return 1;
2147}
2148
2149// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2150// maximum version.
2151static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002152 bssl::UniquePtr<X509> cert = GetTestCertificate();
2153 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2154 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2155 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002156 if (!cert || !key || !server_ctx || !client_ctx ||
2157 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002158 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002159 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2160 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002161 return false;
2162 }
2163
David Benjamin99620572016-08-30 00:35:36 -04002164 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2165
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002166 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002167 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2168 server_ctx.get(), nullptr)) {
2169 return false;
2170 }
2171
2172 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2173 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2174 return false;
2175 }
2176
2177 return true;
2178}
2179
David Benjamin2dc02042016-09-19 19:57:37 -04002180static bool TestSetVersion() {
2181 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2182 if (!ctx) {
2183 return false;
2184 }
2185
David Benjamine4706902016-09-20 15:12:23 -04002186 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2187 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2188 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2189 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002190 fprintf(stderr, "Could not set valid TLS version.\n");
2191 return false;
2192 }
2193
David Benjamine4706902016-09-20 15:12:23 -04002194 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2195 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2196 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2197 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2198 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2199 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002200 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2201 return false;
2202 }
2203
David Benjamine34bcc92016-09-21 16:53:09 -04002204 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2205 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2206 fprintf(stderr, "Could not set default TLS version.\n");
2207 return false;
2208 }
2209
2210 if (ctx->min_version != SSL3_VERSION ||
2211 ctx->max_version != TLS1_2_VERSION) {
2212 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2213 ctx->min_version, ctx->max_version);
2214 return false;
2215 }
2216
David Benjamin2dc02042016-09-19 19:57:37 -04002217 ctx.reset(SSL_CTX_new(DTLS_method()));
2218 if (!ctx) {
2219 return false;
2220 }
2221
David Benjamine4706902016-09-20 15:12:23 -04002222 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2223 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2224 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2225 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002226 fprintf(stderr, "Could not set valid DTLS version.\n");
2227 return false;
2228 }
2229
David Benjamine4706902016-09-20 15:12:23 -04002230 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2231 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2232 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2233 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2234 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2235 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2236 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2237 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002238 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2239 return false;
2240 }
2241
David Benjamine34bcc92016-09-21 16:53:09 -04002242 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2243 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2244 fprintf(stderr, "Could not set default DTLS version.\n");
2245 return false;
2246 }
2247
2248 if (ctx->min_version != TLS1_1_VERSION ||
2249 ctx->max_version != TLS1_2_VERSION) {
2250 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2251 ctx->min_version, ctx->max_version);
2252 return false;
2253 }
2254
David Benjamin2dc02042016-09-19 19:57:37 -04002255 return true;
2256}
2257
David Benjamincb18ac22016-09-27 14:09:15 -04002258static bool TestVersions() {
2259 bssl::UniquePtr<X509> cert = GetTestCertificate();
2260 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2261 if (!cert || !key) {
2262 return false;
2263 }
2264
2265 for (bool is_dtls : std::vector<bool>{false, true}) {
2266 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2267 const char *name = is_dtls ? "DTLS" : "TLS";
2268 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2269 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2270 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2271 for (size_t i = 0; i < num_versions; i++) {
2272 uint16_t version = versions[i];
2273 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2274 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2275 bssl::UniquePtr<SSL> client, server;
2276 if (!server_ctx || !client_ctx ||
2277 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2278 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2279 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2280 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2281 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2282 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2283 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2284 server_ctx.get(), nullptr /* no session */)) {
2285 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2286 version);
2287 return false;
2288 }
2289
2290 if (SSL_version(client.get()) != version ||
2291 SSL_version(server.get()) != version) {
2292 fprintf(stderr,
2293 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2294 SSL_version(client.get()), SSL_version(server.get()), version);
2295 return false;
2296 }
2297 }
2298 }
2299
2300 return true;
2301}
2302
David Benjamin1d128f32015-09-08 17:41:40 -04002303int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002304 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002305
Adam Langley10f97f32016-07-12 08:09:33 -07002306 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002307 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002308 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2309 !TestSSL_SESSIONEncoding(kCustomSession) ||
2310 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2311 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2312 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2313 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002314 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002315 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2316 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2317 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2318 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2319 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2320 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2321 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2322 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2323 !TestCipherGetRFCName() ||
2324 !TestPaddingExtension() ||
2325 !TestClientCAList() ||
2326 !TestInternalSessionCache() ||
2327 !TestSequenceNumber(false /* TLS */) ||
2328 !TestSequenceNumber(true /* DTLS */) ||
2329 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002330 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002331 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002332 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002333 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002334 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002335 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002336 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002337 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002338 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002339 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002340 !TestSetVersion() ||
2341 !TestVersions()) {
Brian Smith83a82982015-04-09 16:21:10 -10002342 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002343 return 1;
2344 }
2345
David Benjamin2e521212014-07-16 14:37:51 -04002346 printf("PASS\n");
2347 return 0;
2348}