blob: eb60550345dc92b7896ed6f726ab2b1f8c690d5d [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()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400927 // Test at TLS 1.2. TLS 1.3 adds enough extensions that the ClientHello is
928 // longer than our test vectors.
929 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
930 !SSL_set_max_proto_version(ssl.get(), TLS1_2_VERSION)) {
David Benjamin422fe082015-07-21 22:03:43 -0400931 return 0;
932 }
David Benjaminafc64de2016-07-19 17:12:41 +0200933 std::vector<uint8_t> client_hello;
934 if (!GetClientHello(ssl.get(), &client_hello) ||
935 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400936 return 0;
937 }
David Benjaminafc64de2016-07-19 17:12:41 +0200938 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400939}
940
941struct PaddingTest {
942 size_t input_len, padded_len;
943};
944
945static const PaddingTest kPaddingTests[] = {
946 // ClientHellos of length below 0x100 do not require padding.
947 {0xfe, 0xfe},
948 {0xff, 0xff},
949 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
950 {0x100, 0x200},
951 {0x123, 0x200},
952 {0x1fb, 0x200},
953 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
954 // padding extension takes a minimum of four bytes plus one required content
955 // byte. (To work around yet more server bugs, we avoid empty final
956 // extensions.)
957 {0x1fc, 0x201},
958 {0x1fd, 0x202},
959 {0x1fe, 0x203},
960 {0x1ff, 0x204},
961 // Finally, larger ClientHellos need no padding.
962 {0x200, 0x200},
963 {0x201, 0x201},
964};
965
966static bool TestPaddingExtension() {
967 // Sample a baseline length.
968 size_t base_len = GetClientHelloLen(1);
969 if (base_len == 0) {
970 return false;
971 }
972
973 for (const PaddingTest &test : kPaddingTests) {
974 if (base_len > test.input_len) {
975 fprintf(stderr, "Baseline ClientHello too long.\n");
976 return false;
977 }
978
979 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
980 if (padded_len != test.padded_len) {
981 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
982 static_cast<unsigned>(test.input_len),
983 static_cast<unsigned>(padded_len),
984 static_cast<unsigned>(test.padded_len));
985 return false;
986 }
987 }
988 return true;
989}
990
David Benjamin1d128f32015-09-08 17:41:40 -0400991// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
992// before configuring as a server.
993static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700994 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400995 if (!ctx) {
996 return false;
997 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700998 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400999 if (!ssl) {
1000 return false;
1001 }
1002
1003 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
1004 if (stack == nullptr) {
1005 return false;
1006 }
1007 // |SSL_set_client_CA_list| takes ownership.
1008 SSL_set_client_CA_list(ssl.get(), stack);
1009
1010 return SSL_get_client_CA_list(ssl.get()) == stack;
1011}
1012
David Benjamin0f653952015-10-18 14:28:01 -04001013static void AppendSession(SSL_SESSION *session, void *arg) {
1014 std::vector<SSL_SESSION*> *out =
1015 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1016 out->push_back(session);
1017}
1018
1019// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1020// order.
1021static bool ExpectCache(SSL_CTX *ctx,
1022 const std::vector<SSL_SESSION*> &expected) {
1023 // Check the linked list.
1024 SSL_SESSION *ptr = ctx->session_cache_head;
1025 for (SSL_SESSION *session : expected) {
1026 if (ptr != session) {
1027 return false;
1028 }
1029 // TODO(davidben): This is an absurd way to denote the end of the list.
1030 if (ptr->next ==
1031 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1032 ptr = nullptr;
1033 } else {
1034 ptr = ptr->next;
1035 }
1036 }
1037 if (ptr != nullptr) {
1038 return false;
1039 }
1040
1041 // Check the hash table.
1042 std::vector<SSL_SESSION*> actual, expected_copy;
1043 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1044 expected_copy = expected;
1045
1046 std::sort(actual.begin(), actual.end());
1047 std::sort(expected_copy.begin(), expected_copy.end());
1048
1049 return actual == expected_copy;
1050}
1051
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001052static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1053 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001054 if (!ret) {
1055 return nullptr;
1056 }
1057
1058 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1059 memset(ret->session_id, 0, ret->session_id_length);
1060 memcpy(ret->session_id, &number, sizeof(number));
1061 return ret;
1062}
1063
David Benjamin0f653952015-10-18 14:28:01 -04001064// Test that the internal session cache behaves as expected.
1065static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001066 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001067 if (!ctx) {
1068 return false;
1069 }
1070
1071 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001072 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001073 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001074 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001075 if (!session) {
1076 return false;
1077 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001078 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001079 }
1080
1081 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1082
1083 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001084 for (const auto &session : sessions) {
1085 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001086 return false;
1087 }
1088 }
1089
1090 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001091 std::vector<SSL_SESSION*> expected = {
1092 sessions[9].get(),
1093 sessions[8].get(),
1094 sessions[7].get(),
1095 sessions[6].get(),
1096 sessions[5].get(),
1097 };
David Benjamin0f653952015-10-18 14:28:01 -04001098 if (!ExpectCache(ctx.get(), expected)) {
1099 return false;
1100 }
1101
1102 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001103 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001104 !ExpectCache(ctx.get(), expected)) {
1105 return false;
1106 }
1107
1108 // Although collisions should be impossible (256-bit session IDs), the cache
1109 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001110 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001111 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1112 return false;
1113 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001114 expected = {
1115 collision.get(),
1116 sessions[9].get(),
1117 sessions[8].get(),
1118 sessions[6].get(),
1119 sessions[5].get(),
1120 };
David Benjamin0f653952015-10-18 14:28:01 -04001121 if (!ExpectCache(ctx.get(), expected)) {
1122 return false;
1123 }
1124
1125 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001126 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001127 return false;
1128 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001129 expected = {
1130 collision.get(),
1131 sessions[9].get(),
1132 sessions[8].get(),
1133 sessions[5].get(),
1134 };
David Benjamin0f653952015-10-18 14:28:01 -04001135 if (!ExpectCache(ctx.get(), expected)) {
1136 return false;
1137 }
1138
1139 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001140 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1141 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001142 !ExpectCache(ctx.get(), expected)) {
1143 return false;
1144 }
1145
1146 return true;
1147}
1148
David Benjaminde942382016-02-11 12:02:01 -05001149static uint16_t EpochFromSequence(uint64_t seq) {
1150 return static_cast<uint16_t>(seq >> 48);
1151}
1152
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001153static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001154 static const char kCertPEM[] =
1155 "-----BEGIN CERTIFICATE-----\n"
1156 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1157 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1158 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1159 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1160 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1161 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1162 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1163 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1164 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1165 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1166 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1167 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1168 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1169 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001170 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1171 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001172}
1173
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001174static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001175 static const char kKeyPEM[] =
1176 "-----BEGIN RSA PRIVATE KEY-----\n"
1177 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1178 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1179 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1180 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1181 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1182 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1183 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1184 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1185 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1186 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1187 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1188 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1189 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1190 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001191 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1192 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001193 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1194}
1195
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001196static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001197 static const char kCertPEM[] =
1198 "-----BEGIN CERTIFICATE-----\n"
1199 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1200 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1201 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1202 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1203 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1204 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1205 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1206 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1207 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1208 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1209 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001210 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1211 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001212}
1213
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001214static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001215 static const char kKeyPEM[] =
1216 "-----BEGIN PRIVATE KEY-----\n"
1217 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1218 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1219 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1220 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001221 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1222 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001223 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1224}
1225
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001226static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001227 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1228 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001229 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001230 if (!client || !server) {
1231 return false;
1232 }
1233 SSL_set_connect_state(client.get());
1234 SSL_set_accept_state(server.get());
1235
David Benjamina20e5352016-08-02 19:09:41 -04001236 SSL_set_session(client.get(), session);
1237
David Benjaminde942382016-02-11 12:02:01 -05001238 BIO *bio1, *bio2;
1239 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1240 return false;
1241 }
1242 // SSL_set_bio takes ownership.
1243 SSL_set_bio(client.get(), bio1, bio1);
1244 SSL_set_bio(server.get(), bio2, bio2);
1245
1246 // Drive both their handshakes to completion.
1247 for (;;) {
1248 int client_ret = SSL_do_handshake(client.get());
1249 int client_err = SSL_get_error(client.get(), client_ret);
1250 if (client_err != SSL_ERROR_NONE &&
1251 client_err != SSL_ERROR_WANT_READ &&
1252 client_err != SSL_ERROR_WANT_WRITE) {
1253 fprintf(stderr, "Client error: %d\n", client_err);
1254 return false;
1255 }
1256
1257 int server_ret = SSL_do_handshake(server.get());
1258 int server_err = SSL_get_error(server.get(), server_ret);
1259 if (server_err != SSL_ERROR_NONE &&
1260 server_err != SSL_ERROR_WANT_READ &&
1261 server_err != SSL_ERROR_WANT_WRITE) {
1262 fprintf(stderr, "Server error: %d\n", server_err);
1263 return false;
1264 }
1265
1266 if (client_ret == 1 && server_ret == 1) {
1267 break;
1268 }
1269 }
1270
David Benjamin686bb192016-05-10 15:15:41 -04001271 *out_client = std::move(client);
1272 *out_server = std::move(server);
1273 return true;
1274}
1275
Steven Valdez2c62fe92016-10-14 12:08:12 -04001276static uint16_t kTLSVersions[] = {
1277 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1278};
David Benjamin686bb192016-05-10 15:15:41 -04001279
Steven Valdez2c62fe92016-10-14 12:08:12 -04001280static uint16_t kDTLSVersions[] = {
1281 DTLS1_VERSION, DTLS1_2_VERSION,
1282};
David Benjamin686bb192016-05-10 15:15:41 -04001283
Steven Valdez2c62fe92016-10-14 12:08:12 -04001284static bool TestSequenceNumber() {
1285 for (bool is_dtls : std::vector<bool>{false, true}) {
1286 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
1287 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
1288 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
1289 : OPENSSL_ARRAY_SIZE(kTLSVersions);
1290 for (size_t i = 0; i < num_versions; i++) {
1291 uint16_t version = versions[i];
1292 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1293 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1294 if (!server_ctx || !client_ctx ||
1295 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1296 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1297 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1298 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1299 return false;
1300 }
David Benjamin686bb192016-05-10 15:15:41 -04001301
Steven Valdez2c62fe92016-10-14 12:08:12 -04001302 bssl::UniquePtr<X509> cert = GetTestCertificate();
1303 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1304 if (!cert || !key ||
1305 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1306 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1307 return false;
1308 }
David Benjaminde942382016-02-11 12:02:01 -05001309
Steven Valdez2c62fe92016-10-14 12:08:12 -04001310 bssl::UniquePtr<SSL> client, server;
1311 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1312 server_ctx.get(), nullptr /* no session */)) {
1313 return false;
1314 }
1315
1316 // Drain any post-handshake messages to ensure there are no unread records
1317 // on either end.
1318 uint8_t byte = 0;
1319 if (SSL_read(client.get(), &byte, 1) > 0 ||
1320 SSL_read(server.get(), &byte, 1) > 0) {
1321 fprintf(stderr, "Received unexpected data.\n");
1322 return false;
1323 }
1324
1325 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1326 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1327 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1328 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1329
1330 if (is_dtls) {
1331 // Both client and server must be at epoch 1.
1332 if (EpochFromSequence(client_read_seq) != 1 ||
1333 EpochFromSequence(client_write_seq) != 1 ||
1334 EpochFromSequence(server_read_seq) != 1 ||
1335 EpochFromSequence(server_write_seq) != 1) {
1336 fprintf(stderr, "Bad epochs.\n");
1337 return false;
1338 }
1339
1340 // The next record to be written should exceed the largest received.
1341 if (client_write_seq <= server_read_seq ||
1342 server_write_seq <= client_read_seq) {
1343 fprintf(stderr, "Inconsistent sequence numbers.\n");
1344 return false;
1345 }
1346 } else {
1347 // The next record to be written should equal the next to be received.
1348 if (client_write_seq != server_read_seq ||
1349 server_write_seq != client_read_seq) {
1350 fprintf(stderr, "Inconsistent sequence numbers.\n");
1351 return false;
1352 }
1353 }
1354
1355 // Send a record from client to server.
1356 if (SSL_write(client.get(), &byte, 1) != 1 ||
1357 SSL_read(server.get(), &byte, 1) != 1) {
1358 fprintf(stderr, "Could not send byte.\n");
1359 return false;
1360 }
1361
1362 // The client write and server read sequence numbers should have
1363 // incremented.
1364 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1365 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1366 fprintf(stderr, "Sequence numbers did not increment.\n");
1367 return false;
1368 }
David Benjaminde942382016-02-11 12:02:01 -05001369 }
David Benjaminde942382016-02-11 12:02:01 -05001370 }
1371
1372 return true;
1373}
1374
David Benjamin686bb192016-05-10 15:15:41 -04001375static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001376 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1377 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001378 if (!client_ctx || !server_ctx) {
1379 return false;
1380 }
1381
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001382 bssl::UniquePtr<X509> cert = GetTestCertificate();
1383 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001384 if (!cert || !key ||
1385 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1386 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1387 return false;
1388 }
1389
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001390 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001391 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001392 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001393 return false;
1394 }
1395
1396 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1397 // one side has shut down.
1398 if (SSL_shutdown(client.get()) != 0) {
1399 fprintf(stderr, "Could not shutdown.\n");
1400 return false;
1401 }
1402
1403 // Reading from the server should consume the EOF.
1404 uint8_t byte;
1405 if (SSL_read(server.get(), &byte, 1) != 0 ||
1406 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1407 fprintf(stderr, "Connection was not shut down cleanly.\n");
1408 return false;
1409 }
1410
1411 // However, the server may continue to write data and then shut down the
1412 // connection.
1413 byte = 42;
1414 if (SSL_write(server.get(), &byte, 1) != 1 ||
1415 SSL_read(client.get(), &byte, 1) != 1 ||
1416 byte != 42) {
1417 fprintf(stderr, "Could not send byte.\n");
1418 return false;
1419 }
1420
1421 // The server may then shutdown the connection.
1422 if (SSL_shutdown(server.get()) != 1 ||
1423 SSL_shutdown(client.get()) != 1) {
1424 fprintf(stderr, "Could not complete shutdown.\n");
1425 return false;
1426 }
1427
1428 return true;
1429}
Steven Valdez87eab492016-06-27 16:34:59 -04001430static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001431 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1432 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001433 if (!client_ctx || !server_ctx) {
1434 return false;
1435 }
1436
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001437 bssl::UniquePtr<X509> cert = GetTestCertificate();
1438 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001439 if (!cert || !key ||
1440 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1441 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1442 return false;
1443 }
1444
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001445 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001446 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001447 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001448 return false;
1449 }
1450
1451 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001452 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001453 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001454 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001455 }
David Benjamin4501bd52016-08-01 13:39:41 -04001456
Steven Valdez84b5c002016-08-25 16:30:58 -04001457 session1->not_resumable = 0;
1458
Steven Valdez87eab492016-06-27 16:34:59 -04001459 uint8_t *s0_bytes, *s1_bytes;
1460 size_t s0_len, s1_len;
1461
1462 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1463 return false;
1464 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001465 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001466
1467 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1468 return false;
1469 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001470 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001471
1472 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1473}
David Benjamin686bb192016-05-10 15:15:41 -04001474
David Benjamin5c0fb882016-06-14 14:03:51 -04001475static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1476 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1477 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1478 SSL_get_wfd(ssl), rfd, wfd);
1479 return false;
1480 }
1481
1482 // The wrapper BIOs are always equal when fds are equal, even if set
1483 // individually.
1484 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1485 fprintf(stderr, "rbio and wbio did not match.\n");
1486 return false;
1487 }
1488
1489 return true;
1490}
1491
1492static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001493 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001494 if (!ctx) {
1495 return false;
1496 }
1497
1498 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001499 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001500 if (!ssl ||
1501 !SSL_set_rfd(ssl.get(), 1) ||
1502 !SSL_set_wfd(ssl.get(), 2) ||
1503 !ExpectFDs(ssl.get(), 1, 2)) {
1504 return false;
1505 }
1506
1507 // Test setting the same FD.
1508 ssl.reset(SSL_new(ctx.get()));
1509 if (!ssl ||
1510 !SSL_set_fd(ssl.get(), 1) ||
1511 !ExpectFDs(ssl.get(), 1, 1)) {
1512 return false;
1513 }
1514
1515 // Test setting the same FD one side at a time.
1516 ssl.reset(SSL_new(ctx.get()));
1517 if (!ssl ||
1518 !SSL_set_rfd(ssl.get(), 1) ||
1519 !SSL_set_wfd(ssl.get(), 1) ||
1520 !ExpectFDs(ssl.get(), 1, 1)) {
1521 return false;
1522 }
1523
1524 // Test setting the same FD in the other order.
1525 ssl.reset(SSL_new(ctx.get()));
1526 if (!ssl ||
1527 !SSL_set_wfd(ssl.get(), 1) ||
1528 !SSL_set_rfd(ssl.get(), 1) ||
1529 !ExpectFDs(ssl.get(), 1, 1)) {
1530 return false;
1531 }
1532
David Benjamin5c0fb882016-06-14 14:03:51 -04001533 // Test changing the read FD partway through.
1534 ssl.reset(SSL_new(ctx.get()));
1535 if (!ssl ||
1536 !SSL_set_fd(ssl.get(), 1) ||
1537 !SSL_set_rfd(ssl.get(), 2) ||
1538 !ExpectFDs(ssl.get(), 2, 1)) {
1539 return false;
1540 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001541
1542 // Test changing the write FD partway through.
1543 ssl.reset(SSL_new(ctx.get()));
1544 if (!ssl ||
1545 !SSL_set_fd(ssl.get(), 1) ||
1546 !SSL_set_wfd(ssl.get(), 2) ||
1547 !ExpectFDs(ssl.get(), 1, 2)) {
1548 return false;
1549 }
1550
1551 // Test a no-op change to the read FD partway through.
1552 ssl.reset(SSL_new(ctx.get()));
1553 if (!ssl ||
1554 !SSL_set_fd(ssl.get(), 1) ||
1555 !SSL_set_rfd(ssl.get(), 1) ||
1556 !ExpectFDs(ssl.get(), 1, 1)) {
1557 return false;
1558 }
1559
1560 // Test a no-op change to the write FD partway through.
1561 ssl.reset(SSL_new(ctx.get()));
1562 if (!ssl ||
1563 !SSL_set_fd(ssl.get(), 1) ||
1564 !SSL_set_wfd(ssl.get(), 1) ||
1565 !ExpectFDs(ssl.get(), 1, 1)) {
1566 return false;
1567 }
1568
1569 // ASan builds will implicitly test that the internal |BIO| reference-counting
1570 // is correct.
1571
1572 return true;
1573}
1574
David Benjamin4501bd52016-08-01 13:39:41 -04001575static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001576 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001577 if (!ctx) {
1578 return false;
1579 }
1580
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001581 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1582 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001583 bio3(BIO_new(BIO_s_mem()));
1584 if (!ssl || !bio1 || !bio2 || !bio3) {
1585 return false;
1586 }
1587
1588 // SSL_set_bio takes one reference when the parameters are the same.
1589 BIO_up_ref(bio1.get());
1590 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1591
1592 // Repeating the call does nothing.
1593 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1594
1595 // It takes one reference each when the parameters are different.
1596 BIO_up_ref(bio2.get());
1597 BIO_up_ref(bio3.get());
1598 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1599
1600 // Repeating the call does nothing.
1601 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1602
1603 // It takes one reference when changing only wbio.
1604 BIO_up_ref(bio1.get());
1605 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1606
1607 // It takes one reference when changing only rbio and the two are different.
1608 BIO_up_ref(bio3.get());
1609 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1610
1611 // If setting wbio to rbio, it takes no additional references.
1612 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1613
1614 // From there, wbio may be switched to something else.
1615 BIO_up_ref(bio1.get());
1616 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1617
1618 // If setting rbio to wbio, it takes no additional references.
1619 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1620
1621 // From there, rbio may be switched to something else, but, for historical
1622 // reasons, it takes a reference to both parameters.
1623 BIO_up_ref(bio1.get());
1624 BIO_up_ref(bio2.get());
1625 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1626
1627 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1628 // is correct.
1629 return true;
1630}
1631
David Benjamin25490f22016-07-14 00:22:54 -04001632static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1633
David Benjaminadd5e522016-07-14 00:33:24 -04001634static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001635 bssl::UniquePtr<X509> cert = GetTestCertificate();
1636 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001637 if (!cert || !key) {
1638 return false;
1639 }
1640
David Benjamincb18ac22016-09-27 14:09:15 -04001641 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001642 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001643 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001644 if (!ctx ||
1645 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001646 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001647 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1648 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001649 return false;
1650 }
David Benjaminadd5e522016-07-14 00:33:24 -04001651 SSL_CTX_set_verify(
1652 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1653 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1654
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001655 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001656 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1657 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001658 return false;
1659 }
1660
1661 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001662 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001663 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1664 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1665 return false;
1666 }
1667
1668 peer.reset(SSL_get_peer_certificate(client.get()));
1669 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1670 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1671 return false;
1672 }
1673
1674 // However, for historical reasons, the chain includes the leaf on the
1675 // client, but does not on the server.
1676 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1677 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1678 return false;
1679 }
1680
1681 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1682 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1683 return false;
1684 }
1685 }
1686
1687 return true;
1688}
1689
David Benjamin25490f22016-07-14 00:22:54 -04001690static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001691 bssl::UniquePtr<X509> cert = GetTestCertificate();
1692 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001693 if (!cert || !key) {
1694 return false;
1695 }
1696
1697 uint8_t *cert_der = NULL;
1698 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1699 if (cert_der_len < 0) {
1700 return false;
1701 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001702 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001703
1704 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1705 SHA256(cert_der, cert_der_len, cert_sha256);
1706
David Benjamincb18ac22016-09-27 14:09:15 -04001707 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001708 // Configure both client and server to accept any certificate, but the
1709 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001710 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001711 if (!ctx ||
1712 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001713 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001714 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1715 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001716 return false;
1717 }
David Benjamin25490f22016-07-14 00:22:54 -04001718 SSL_CTX_set_verify(
1719 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1720 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1721 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1722
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001723 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001724 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1725 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001726 return false;
1727 }
1728
1729 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001730 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001731 if (peer) {
1732 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1733 return false;
1734 }
1735
1736 SSL_SESSION *session = SSL_get_session(server.get());
1737 if (!session->peer_sha256_valid) {
1738 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1739 return false;
1740 }
1741
1742 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1743 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1744 return false;
1745 }
1746 }
1747
1748 return true;
1749}
1750
David Benjaminafc64de2016-07-19 17:12:41 +02001751static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1752 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001753 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001754 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001755 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001756 // Our default cipher list varies by CPU capabilities, so manually place
1757 // the ChaCha20 ciphers in front.
1758 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001759 return false;
1760 }
David Benjamin2dc02042016-09-19 19:57:37 -04001761
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001762 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001763 if (!ssl) {
1764 return false;
1765 }
1766 std::vector<uint8_t> client_hello;
1767 if (!GetClientHello(ssl.get(), &client_hello)) {
1768 return false;
1769 }
1770
1771 // Zero the client_random.
1772 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1773 1 + 3 + // handshake message header
1774 2; // client_version
1775 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1776 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1777 return false;
1778 }
1779 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1780
1781 if (client_hello.size() != expected_len ||
1782 memcmp(client_hello.data(), expected, expected_len) != 0) {
1783 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1784 fprintf(stderr, "Got:\n\t");
1785 for (size_t i = 0; i < client_hello.size(); i++) {
1786 fprintf(stderr, "0x%02x, ", client_hello[i]);
1787 }
1788 fprintf(stderr, "\nWanted:\n\t");
1789 for (size_t i = 0; i < expected_len; i++) {
1790 fprintf(stderr, "0x%02x, ", expected[i]);
1791 }
1792 fprintf(stderr, "\n");
1793 return false;
1794 }
1795
1796 return true;
1797}
1798
1799// Tests that our ClientHellos do not change unexpectedly.
1800static bool TestClientHello() {
1801 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001802 0x16,
1803 0x03, 0x00,
1804 0x00, 0x3f,
1805 0x01,
1806 0x00, 0x00, 0x3b,
1807 0x03, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00,
1813 0x00, 0x14,
1814 0xc0, 0x09,
1815 0xc0, 0x13,
1816 0x00, 0x33,
1817 0xc0, 0x0a,
1818 0xc0, 0x14,
1819 0x00, 0x39,
1820 0x00, 0x2f,
1821 0x00, 0x35,
1822 0x00, 0x0a,
1823 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001824 };
1825 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1826 sizeof(kSSL3ClientHello))) {
1827 return false;
1828 }
1829
1830 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001831 0x16,
1832 0x03, 0x01,
1833 0x00, 0x5e,
1834 0x01,
1835 0x00, 0x00, 0x5a,
1836 0x03, 0x01,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00,
1842 0x00, 0x12,
1843 0xc0, 0x09,
1844 0xc0, 0x13,
1845 0x00, 0x33,
1846 0xc0, 0x0a,
1847 0xc0, 0x14,
1848 0x00, 0x39,
1849 0x00, 0x2f,
1850 0x00, 0x35,
1851 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001852 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1853 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1854 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1855 };
1856 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1857 sizeof(kTLS1ClientHello))) {
1858 return false;
1859 }
1860
1861 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001862 0x16,
1863 0x03, 0x01,
1864 0x00, 0x5e,
1865 0x01,
1866 0x00, 0x00, 0x5a,
1867 0x03, 0x02,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1872 0x00,
1873 0x00, 0x12,
1874 0xc0, 0x09,
1875 0xc0, 0x13,
1876 0x00, 0x33,
1877 0xc0, 0x0a,
1878 0xc0, 0x14,
1879 0x00, 0x39,
1880 0x00, 0x2f,
1881 0x00, 0x35,
1882 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001883 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1884 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1885 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1886 };
1887 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1888 sizeof(kTLS11ClientHello))) {
1889 return false;
1890 }
1891
1892 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001893 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1897 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1898 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1899 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1900 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001901 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001902 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001903 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1904 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001905 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1906 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001907 };
1908 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1909 sizeof(kTLS12ClientHello))) {
1910 return false;
1911 }
1912
1913 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1914 // implementation has settled enough that it won't change.
1915
1916 return true;
1917}
1918
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001919static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001920
1921static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1922 // Save the most recent session.
1923 g_last_session.reset(session);
1924 return 1;
1925}
1926
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001927static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001928 SSL_CTX *server_ctx) {
1929 g_last_session = nullptr;
1930 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1931
1932 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001933 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001934 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1935 nullptr /* no session */)) {
1936 fprintf(stderr, "Failed to connect client and server.\n");
1937 return nullptr;
1938 }
1939
1940 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1941 SSL_read(client.get(), nullptr, 0);
1942
1943 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1944
1945 if (!g_last_session) {
1946 fprintf(stderr, "Client did not receive a session.\n");
1947 return nullptr;
1948 }
1949 return std::move(g_last_session);
1950}
1951
1952static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1953 SSL_SESSION *session,
1954 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001955 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001956 if (!ConnectClientAndServer(&client, &server, client_ctx,
1957 server_ctx, session)) {
1958 fprintf(stderr, "Failed to connect client and server.\n");
1959 return false;
1960 }
1961
1962 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1963 fprintf(stderr, "Client and server were inconsistent.\n");
1964 return false;
1965 }
1966
1967 bool was_reused = !!SSL_session_reused(client.get());
1968 if (was_reused != reused) {
1969 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1970 was_reused ? "" : " not");
1971 return false;
1972 }
1973
1974 return true;
1975}
1976
1977static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001978 bssl::UniquePtr<X509> cert = GetTestCertificate();
1979 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001980 if (!cert || !key) {
1981 return false;
1982 }
1983
1984 static const uint8_t kContext1[] = {1};
1985 static const uint8_t kContext2[] = {2};
1986
David Benjamincb18ac22016-09-27 14:09:15 -04001987 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001988 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1989 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001990 if (!server_ctx || !client_ctx ||
1991 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1992 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1993 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001994 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001995 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1996 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1997 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1998 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001999 return false;
2000 }
2001
David Benjamina20e5352016-08-02 19:09:41 -04002002 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002003 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2004
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002005 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04002006 CreateClientSession(client_ctx.get(), server_ctx.get());
2007 if (!session) {
2008 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2009 return false;
2010 }
2011
2012 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2013 true /* expect session reused */)) {
2014 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2015 return false;
2016 }
2017
2018 // Change the session ID context.
2019 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2020 sizeof(kContext2))) {
2021 return false;
2022 }
2023
2024 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2025 false /* expect session not reused */)) {
2026 fprintf(stderr,
2027 "Error connection with different context (version = %04x).\n",
2028 version);
2029 return false;
2030 }
2031 }
2032
2033 return true;
2034}
2035
David Benjamin721e8b72016-08-03 13:13:17 -04002036static timeval g_current_time;
2037
2038static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2039 *out_clock = g_current_time;
2040}
2041
2042static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002043 bssl::UniquePtr<X509> cert = GetTestCertificate();
2044 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002045 if (!cert || !key) {
2046 return false;
2047 }
2048
David Benjamincb18ac22016-09-27 14:09:15 -04002049 for (uint16_t version : kTLSVersions) {
David Benjaminb2e2e322016-11-01 17:32:54 -04002050 for (bool server_test : std::vector<bool>{false, true}) {
2051 static const int kStartTime = 1000;
2052 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002053
David Benjaminb2e2e322016-11-01 17:32:54 -04002054 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2055 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2056 if (!server_ctx || !client_ctx ||
2057 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2058 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2059 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2060 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2061 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2062 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2063 return false;
2064 }
David Benjamin721e8b72016-08-03 13:13:17 -04002065
David Benjaminb2e2e322016-11-01 17:32:54 -04002066 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2067 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamin721e8b72016-08-03 13:13:17 -04002068
David Benjaminb2e2e322016-11-01 17:32:54 -04002069 // Both client and server must enforce session timeouts.
2070 if (server_test) {
2071 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2072 } else {
2073 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2074 }
David Benjamin721e8b72016-08-03 13:13:17 -04002075
David Benjaminb2e2e322016-11-01 17:32:54 -04002076 bssl::UniquePtr<SSL_SESSION> session =
2077 CreateClientSession(client_ctx.get(), server_ctx.get());
2078 if (!session) {
2079 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2080 return false;
2081 }
David Benjamin721e8b72016-08-03 13:13:17 -04002082
David Benjaminb2e2e322016-11-01 17:32:54 -04002083 // Advance the clock just behind the timeout.
2084 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
David Benjamin721e8b72016-08-03 13:13:17 -04002085
David Benjaminb2e2e322016-11-01 17:32:54 -04002086 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2087 session.get(),
2088 true /* expect session reused */)) {
2089 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2090 return false;
2091 }
David Benjamin721e8b72016-08-03 13:13:17 -04002092
David Benjaminb2e2e322016-11-01 17:32:54 -04002093 // Advance the clock one more second.
2094 g_current_time.tv_sec++;
David Benjamin721e8b72016-08-03 13:13:17 -04002095
David Benjaminb2e2e322016-11-01 17:32:54 -04002096 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2097 session.get(),
2098 false /* expect session not reused */)) {
2099 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2100 return false;
2101 }
David Benjamin1b22f852016-10-27 16:36:32 -04002102
David Benjaminb2e2e322016-11-01 17:32:54 -04002103 // Rewind the clock to before the session was minted.
2104 g_current_time.tv_sec = kStartTime - 1;
David Benjamin1b22f852016-10-27 16:36:32 -04002105
David Benjaminb2e2e322016-11-01 17:32:54 -04002106 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2107 session.get(),
2108 false /* expect session not reused */)) {
2109 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2110 return false;
2111 }
David Benjamin1b22f852016-10-27 16:36:32 -04002112 }
David Benjamin721e8b72016-08-03 13:13:17 -04002113 }
2114
2115 return true;
2116}
2117
David Benjamin0fc37ef2016-08-17 15:29:46 -04002118static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2119 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2120 SSL_set_SSL_CTX(ssl, ctx);
2121 return SSL_TLSEXT_ERR_OK;
2122}
2123
2124static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002125 bssl::UniquePtr<X509> cert = GetTestCertificate();
2126 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2127 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2128 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002129 if (!cert || !key || !cert2 || !key2) {
2130 return false;
2131 }
2132
2133 // At each version, test that switching the |SSL_CTX| at the SNI callback
2134 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002135 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002136 if (version == SSL3_VERSION) {
2137 continue;
2138 }
2139
2140 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2141
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002142 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2143 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2144 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002145 if (!server_ctx || !server_ctx2 || !client_ctx ||
2146 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2147 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2148 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2149 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2150 // Historically signing preferences would be lost in some cases with the
2151 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2152 // this doesn't happen when |version| is TLS 1.2, configure the private
2153 // key to only sign SHA-256.
2154 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002155 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002156 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2157 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2158 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2159 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2160 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2161 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002162 return false;
2163 }
2164
David Benjamin0fc37ef2016-08-17 15:29:46 -04002165 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2166 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2167
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002168 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002169 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2170 server_ctx.get(), nullptr)) {
2171 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2172 return false;
2173 }
2174
2175 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002176 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002177 if (!peer ||
2178 X509_cmp(peer.get(), cert2.get()) != 0) {
2179 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2180 version);
2181 return false;
2182 }
2183 }
2184
2185 return true;
2186}
2187
David Benjamin99620572016-08-30 00:35:36 -04002188static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002189 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002190 return -1;
2191 }
2192
David Benjamin99620572016-08-30 00:35:36 -04002193 return 1;
2194}
2195
2196// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2197// maximum version.
2198static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002199 bssl::UniquePtr<X509> cert = GetTestCertificate();
2200 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2201 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2202 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002203 if (!cert || !key || !server_ctx || !client_ctx ||
2204 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002205 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002206 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2207 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002208 return false;
2209 }
2210
David Benjamin99620572016-08-30 00:35:36 -04002211 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2212
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002213 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002214 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2215 server_ctx.get(), nullptr)) {
2216 return false;
2217 }
2218
2219 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2220 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2221 return false;
2222 }
2223
2224 return true;
2225}
2226
David Benjamin2dc02042016-09-19 19:57:37 -04002227static bool TestSetVersion() {
2228 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2229 if (!ctx) {
2230 return false;
2231 }
2232
David Benjamine4706902016-09-20 15:12:23 -04002233 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2234 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2235 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2236 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002237 fprintf(stderr, "Could not set valid TLS version.\n");
2238 return false;
2239 }
2240
David Benjamine4706902016-09-20 15:12:23 -04002241 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2242 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2243 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2244 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2245 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2246 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002247 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2248 return false;
2249 }
2250
David Benjamine34bcc92016-09-21 16:53:09 -04002251 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2252 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2253 fprintf(stderr, "Could not set default TLS version.\n");
2254 return false;
2255 }
2256
2257 if (ctx->min_version != SSL3_VERSION ||
2258 ctx->max_version != TLS1_2_VERSION) {
2259 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2260 ctx->min_version, ctx->max_version);
2261 return false;
2262 }
2263
David Benjamin2dc02042016-09-19 19:57:37 -04002264 ctx.reset(SSL_CTX_new(DTLS_method()));
2265 if (!ctx) {
2266 return false;
2267 }
2268
David Benjamine4706902016-09-20 15:12:23 -04002269 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2270 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2271 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2272 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002273 fprintf(stderr, "Could not set valid DTLS version.\n");
2274 return false;
2275 }
2276
David Benjamine4706902016-09-20 15:12:23 -04002277 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2278 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2279 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2280 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2281 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2282 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2283 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2284 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002285 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2286 return false;
2287 }
2288
David Benjamine34bcc92016-09-21 16:53:09 -04002289 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2290 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2291 fprintf(stderr, "Could not set default DTLS version.\n");
2292 return false;
2293 }
2294
2295 if (ctx->min_version != TLS1_1_VERSION ||
2296 ctx->max_version != TLS1_2_VERSION) {
2297 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2298 ctx->min_version, ctx->max_version);
2299 return false;
2300 }
2301
David Benjamin2dc02042016-09-19 19:57:37 -04002302 return true;
2303}
2304
David Benjamincb18ac22016-09-27 14:09:15 -04002305static bool TestVersions() {
2306 bssl::UniquePtr<X509> cert = GetTestCertificate();
2307 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2308 if (!cert || !key) {
2309 return false;
2310 }
2311
2312 for (bool is_dtls : std::vector<bool>{false, true}) {
2313 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2314 const char *name = is_dtls ? "DTLS" : "TLS";
2315 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2316 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2317 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2318 for (size_t i = 0; i < num_versions; i++) {
2319 uint16_t version = versions[i];
2320 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2321 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2322 bssl::UniquePtr<SSL> client, server;
2323 if (!server_ctx || !client_ctx ||
2324 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2325 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2326 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2327 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2328 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2329 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2330 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2331 server_ctx.get(), nullptr /* no session */)) {
2332 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2333 version);
2334 return false;
2335 }
2336
2337 if (SSL_version(client.get()) != version ||
2338 SSL_version(server.get()) != version) {
2339 fprintf(stderr,
2340 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2341 SSL_version(client.get()), SSL_version(server.get()), version);
2342 return false;
2343 }
2344 }
2345 }
2346
2347 return true;
2348}
2349
David Benjamin9ef31f02016-10-31 18:01:13 -04002350// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2351// selection callback.
2352static bool TestALPNCipherAvailable() {
2353 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2354
2355 bssl::UniquePtr<X509> cert = GetTestCertificate();
2356 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2357 if (!cert || !key) {
2358 return false;
2359 }
2360
2361 for (uint16_t version : kTLSVersions) {
2362 // SSL 3.0 lacks extensions.
2363 if (version == SSL3_VERSION) {
2364 continue;
2365 }
2366
2367 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2368 if (!ctx ||
2369 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2370 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2371 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2372 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2373 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2374 0) {
2375 return false;
2376 }
2377
2378 // The ALPN callback does not fail the handshake on error, so have the
2379 // callback write a boolean.
2380 bool pending_cipher_known = false;
2381 SSL_CTX_set_alpn_select_cb(
2382 ctx.get(),
2383 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2384 unsigned in_len, void *arg) -> int {
2385 bool *result = reinterpret_cast<bool *>(arg);
2386 *result = SSL_get_pending_cipher(ssl) != nullptr;
2387 return SSL_TLSEXT_ERR_NOACK;
2388 },
2389 &pending_cipher_known);
2390
2391 bssl::UniquePtr<SSL> client, server;
2392 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2393 nullptr /* no session */)) {
2394 return false;
2395 }
2396
2397 if (!pending_cipher_known) {
2398 fprintf(stderr,
2399 "%x: The pending cipher was not known in the ALPN callback.\n",
2400 version);
2401 return false;
2402 }
2403 }
2404
2405 return true;
2406}
2407
David Benjamin1d128f32015-09-08 17:41:40 -04002408int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002409 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002410
Adam Langley10f97f32016-07-12 08:09:33 -07002411 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002412 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002413 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2414 !TestSSL_SESSIONEncoding(kCustomSession) ||
2415 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2416 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2417 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2418 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002419 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002420 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2421 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2422 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2423 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2424 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2425 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2426 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2427 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2428 !TestCipherGetRFCName() ||
2429 !TestPaddingExtension() ||
2430 !TestClientCAList() ||
2431 !TestInternalSessionCache() ||
Steven Valdez2c62fe92016-10-14 12:08:12 -04002432 !TestSequenceNumber() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002433 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002434 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002435 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002436 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002437 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002438 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002439 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002440 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002441 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002442 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002443 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002444 !TestSetVersion() ||
David Benjamin9ef31f02016-10-31 18:01:13 -04002445 !TestVersions() ||
2446 !TestALPNCipherAvailable()) {
Brian Smith83a82982015-04-09 16:21:10 -10002447 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002448 return 1;
2449 }
2450
David Benjamin2e521212014-07-16 14:37:51 -04002451 printf("PASS\n");
2452 return 0;
2453}