blob: 9bdaad2c1576f64a02847f0c82bef9ce2fc58c45 [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 Benjamin3c51d9b2016-11-01 17:50:42 -040026#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040027#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040028#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040029#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050030#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040031#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040033#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050034#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035
Steven Valdez87eab492016-06-27 16:34:59 -040036#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040037#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020038#include "../crypto/test/test_util.h"
39
David Benjamin721e8b72016-08-03 13:13:17 -040040#if defined(OPENSSL_WINDOWS)
41/* Windows defines struct timeval in winsock2.h. */
42OPENSSL_MSVC_PRAGMA(warning(push, 3))
43#include <winsock2.h>
44OPENSSL_MSVC_PRAGMA(warning(pop))
45#else
46#include <sys/time.h>
47#endif
48
David Benjamin1d77e562015-03-22 17:22:08 -040049
50struct ExpectedCipher {
51 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040052 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040053};
David Benjaminbb0a17c2014-09-20 15:35:39 -040054
David Benjamin1d77e562015-03-22 17:22:08 -040055struct CipherTest {
56 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040057 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050058 // The list of expected ciphers, in order.
59 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040060};
David Benjaminbb0a17c2014-09-20 15:35:39 -040061
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010062struct CurveTest {
63 // The rule string to apply.
64 const char *rule;
65 // The list of expected curves, in order.
66 std::vector<uint16_t> expected;
67};
68
David Benjaminfb974e62015-12-16 19:34:22 -050069static const CipherTest kCipherTests[] = {
70 // Selecting individual ciphers should work.
71 {
72 "ECDHE-ECDSA-CHACHA20-POLY1305:"
73 "ECDHE-RSA-CHACHA20-POLY1305:"
74 "ECDHE-ECDSA-AES128-GCM-SHA256:"
75 "ECDHE-RSA-AES128-GCM-SHA256",
76 {
77 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
78 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
80 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
81 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
82 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
83 },
84 },
85 // + reorders selected ciphers to the end, keeping their relative order.
86 {
87 "ECDHE-ECDSA-CHACHA20-POLY1305:"
88 "ECDHE-RSA-CHACHA20-POLY1305:"
89 "ECDHE-ECDSA-AES128-GCM-SHA256:"
90 "ECDHE-RSA-AES128-GCM-SHA256:"
91 "+aRSA",
92 {
93 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
96 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
97 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
98 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
99 },
100 },
101 // ! banishes ciphers from future selections.
102 {
103 "!aRSA:"
104 "ECDHE-ECDSA-CHACHA20-POLY1305:"
105 "ECDHE-RSA-CHACHA20-POLY1305:"
106 "ECDHE-ECDSA-AES128-GCM-SHA256:"
107 "ECDHE-RSA-AES128-GCM-SHA256",
108 {
109 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
110 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
111 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
112 },
113 },
114 // Multiple masks can be ANDed in a single rule.
115 {
116 "kRSA+AESGCM+AES128",
117 {
118 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
119 },
120 },
121 // - removes selected ciphers, but preserves their order for future
122 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
123 // ECDHE_RSA.
124 {
125 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
126 "AESGCM+AES128+aRSA",
127 {
128 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
129 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
130 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
131 },
132 },
133 // Unknown selectors are no-ops.
134 {
135 "ECDHE-ECDSA-CHACHA20-POLY1305:"
136 "ECDHE-RSA-CHACHA20-POLY1305:"
137 "ECDHE-ECDSA-AES128-GCM-SHA256:"
138 "ECDHE-RSA-AES128-GCM-SHA256:"
139 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
140 {
141 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
142 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
144 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
145 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
146 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
147 },
148 },
149 // Square brackets specify equi-preference groups.
150 {
151 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
152 "[ECDHE-RSA-CHACHA20-POLY1305]:"
153 "ECDHE-RSA-AES128-GCM-SHA256",
154 {
155 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
157 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
158 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
159 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
160 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
161 },
162 },
163 // @STRENGTH performs a stable strength-sort of the selected ciphers and
164 // only the selected ciphers.
165 {
166 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500168 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
169 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700170 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500171 // Select ECDHE ones and sort them by strength. Ties should resolve
172 // based on the order above.
173 "kECDHE:@STRENGTH:-ALL:"
174 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
175 // by strength. Then RSA, backwards by strength.
176 "aRSA",
177 {
178 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
179 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
180 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500181 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500182 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
183 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
184 },
185 },
186 // Exact ciphers may not be used in multi-part rules; they are treated
187 // as unknown aliases.
188 {
189 "ECDHE-ECDSA-AES128-GCM-SHA256:"
190 "ECDHE-RSA-AES128-GCM-SHA256:"
191 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
192 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
193 {
194 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
195 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
196 },
197 },
198 // SSLv3 matches everything that existed before TLS 1.2.
199 {
200 "AES128-SHA:AES128-SHA256:!SSLv3",
201 {
202 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
203 },
204 },
205 // TLSv1.2 matches everything added in TLS 1.2.
206 {
207 "AES128-SHA:AES128-SHA256:!TLSv1.2",
208 {
209 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
210 },
211 },
212 // The two directives have no intersection.
213 {
214 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
215 {
216 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
217 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
218 },
219 },
220 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
221 // name and not an alias. It may not be used in a multipart rule. (That the
222 // shared name works is covered by the standard tests.)
223 {
224 "ECDHE-ECDSA-CHACHA20-POLY1305:"
225 "ECDHE-RSA-CHACHA20-POLY1305:"
226 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
227 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
228 {
229 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
230 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
231 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
232 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
233 },
234 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235};
236
237static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400238 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400239 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
240 "RSA]",
241 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400242 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400243 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400244 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400245 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400246 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400247 "",
248 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400249 // COMPLEMENTOFDEFAULT is empty.
250 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400251 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400252 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400253 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
255 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
256 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
257 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700258 // Opcode supplied, but missing selector.
259 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400260};
261
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700262static const char *kMustNotIncludeNull[] = {
263 "ALL",
264 "DEFAULT",
265 "ALL:!eNULL",
266 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500267 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700268 "FIPS",
269 "SHA",
270 "SHA1",
271 "RSA",
272 "SSLv3",
273 "TLSv1",
274 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700275};
276
Matt Braithwaite053931e2016-05-25 12:06:05 -0700277static const char *kMustNotIncludeCECPQ1[] = {
278 "ALL",
279 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700280 "HIGH",
281 "FIPS",
282 "SHA",
283 "SHA1",
284 "SHA256",
285 "SHA384",
286 "RSA",
287 "SSLv3",
288 "TLSv1",
289 "TLSv1.2",
290 "aRSA",
291 "RSA",
292 "aECDSA",
293 "ECDSA",
294 "AES",
295 "AES128",
296 "AES256",
297 "AESGCM",
298 "CHACHA20",
299};
300
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100301static const CurveTest kCurveTests[] = {
302 {
303 "P-256",
304 { SSL_CURVE_SECP256R1 },
305 },
306 {
307 "P-256:P-384:P-521:X25519",
308 {
309 SSL_CURVE_SECP256R1,
310 SSL_CURVE_SECP384R1,
311 SSL_CURVE_SECP521R1,
312 SSL_CURVE_X25519,
313 },
314 },
315};
316
317static const char *kBadCurvesLists[] = {
318 "",
319 ":",
320 "::",
321 "P-256::X25519",
322 "RSA:P-256",
323 "P-256:RSA",
324 "X25519:P-256:",
325 ":X25519:P-256",
326};
327
David Benjamin1d77e562015-03-22 17:22:08 -0400328static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
329 bool in_group = false;
330 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400331 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
332 if (!in_group && list->in_group_flags[i]) {
333 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400334 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400335 }
336 fprintf(stderr, "\t");
337 if (in_group) {
338 fprintf(stderr, " ");
339 }
340 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
341 if (in_group && !list->in_group_flags[i]) {
342 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400343 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400344 }
345 }
346}
347
David Benjaminfb974e62015-12-16 19:34:22 -0500348static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700349 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400350 if (!ctx) {
351 return false;
David Benjamin65226252015-02-05 16:49:47 -0500352 }
353
David Benjaminfb974e62015-12-16 19:34:22 -0500354 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
355 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400356 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400357 }
358
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500360 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
361 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
362 PrintCipherPreferenceList(ctx->cipher_list);
363 return false;
364 }
365
366 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400367 const SSL_CIPHER *cipher =
368 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500369 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
370 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
371 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400372 PrintCipherPreferenceList(ctx->cipher_list);
373 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400374 }
375 }
376
David Benjamin1d77e562015-03-22 17:22:08 -0400377 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400378}
379
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700380static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700381 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700382 if (!ctx) {
383 return false;
384 }
385 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
386 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
387 return false;
388 }
389 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
390 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
391 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
392 return false;
393 }
394 }
395 return true;
396}
397
Matt Braithwaite053931e2016-05-25 12:06:05 -0700398static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700399 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700400 if (!ctx) {
401 return false;
402 }
403 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
404 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
405 return false;
406 }
407 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
408 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
409 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
410 return false;
411 }
412 }
413 return true;
414}
415
David Benjamin1d77e562015-03-22 17:22:08 -0400416static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500417 for (const CipherTest &test : kCipherTests) {
418 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400419 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400420 }
421 }
422
David Benjaminfb974e62015-12-16 19:34:22 -0500423 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700424 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400425 if (!ctx) {
426 return false;
David Benjamin65226252015-02-05 16:49:47 -0500427 }
David Benjaminfb974e62015-12-16 19:34:22 -0500428 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
429 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400430 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400431 }
432 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400433 }
434
David Benjaminfb974e62015-12-16 19:34:22 -0500435 for (const char *rule : kMustNotIncludeNull) {
436 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700437 return false;
438 }
439 }
440
Matt Braithwaite053931e2016-05-25 12:06:05 -0700441 for (const char *rule : kMustNotIncludeCECPQ1) {
442 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
443 return false;
444 }
445 }
446
David Benjamin1d77e562015-03-22 17:22:08 -0400447 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448}
David Benjamin2e521212014-07-16 14:37:51 -0400449
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100450static bool TestCurveRule(const CurveTest &t) {
451 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
452 if (!ctx) {
453 return false;
454 }
455
456 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
457 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
458 return false;
459 }
460
461 // Compare the two lists.
462 if (ctx->supported_group_list_len != t.expected.size()) {
463 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
464 return false;
465 }
466
467 for (size_t i = 0; i < t.expected.size(); i++) {
468 if (t.expected[i] != ctx->supported_group_list[i]) {
469 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
470 return false;
471 }
472 }
473
474 return true;
475}
476
477static bool TestCurveRules() {
478 for (const CurveTest &test : kCurveTests) {
479 if (!TestCurveRule(test)) {
480 return false;
481 }
482 }
483
484 for (const char *rule : kBadCurvesLists) {
485 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
486 if (!ctx) {
487 return false;
488 }
489 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
490 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
491 return false;
492 }
493 ERR_clear_error();
494 }
495
496 return true;
497}
498
Adam Langley10f97f32016-07-12 08:09:33 -0700499// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
500// s_client -sess_out.
501static const char kOpenSSLSession[] =
502 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
503 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
504 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
505 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
506 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
507 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
508 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
509 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
510 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
511 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
512 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
513 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
514 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
515 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
516 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
517 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
518 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
519 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
520 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
521 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
522 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
523 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
524 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
525 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
526 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
527 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
528 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
529 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
530 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
531 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
532 "i4gv7Y5oliyn";
533
534// kCustomSession is a custom serialized SSL_SESSION generated by
535// filling in missing fields from |kOpenSSLSession|. This includes
536// providing |peer_sha256|, so |peer| is not serialized.
537static const char kCustomSession[] =
538 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
539 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
540 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
541 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
542 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
543 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
544 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
545 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
546
547// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
548static const char kBoringSSLSession[] =
549 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
550 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
551 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
552 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
553 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
554 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
555 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
556 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
557 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
558 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
559 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
560 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
561 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
562 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
563 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
564 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
565 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
566 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
567 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
568 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
569 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
570 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
571 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
572 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
573 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
574 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
575 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
576 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
577 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
578 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
579 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
580 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
581 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
582 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
583 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
584 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
585 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
586 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
587 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
588 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
589 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
590 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
591 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
592 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
593 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
594 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
595 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
596 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
597 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
598 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
599 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
600 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
601 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
602 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
603 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
604 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
605 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
606 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
607 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
608 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
609 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
610 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
611 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
612 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
613 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
614 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
615 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
616 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
617 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
618 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
619 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
620 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
621 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
622 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
623 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
624 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
625 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
626 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
627 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
628 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
629 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
630 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
631 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
632 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
633 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
634 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
635 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
636 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
637 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
638 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
639 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
640 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
641 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
642 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
643 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
644
645// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
646// the final (optional) element of |kCustomSession| with tag number 30.
647static const char kBadSessionExtraField[] =
648 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
649 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
650 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
651 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
652 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
653 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
654 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
655 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
656
657// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
658// the version of |kCustomSession| with 2.
659static const char kBadSessionVersion[] =
660 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
661 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
662 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
663 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
664 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
665 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
666 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
667 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
668
669// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
670// appended.
671static const char kBadSessionTrailingData[] =
672 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
673 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
674 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
675 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
676 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
677 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
678 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
679 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
680
David Benjamin1d77e562015-03-22 17:22:08 -0400681static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400682 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400683 if (!EVP_DecodedLength(&len, strlen(in))) {
684 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400685 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400686 }
687
David Benjamin1d77e562015-03-22 17:22:08 -0400688 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800689 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400690 strlen(in))) {
691 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400692 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400693 }
David Benjamin1d77e562015-03-22 17:22:08 -0400694 out->resize(len);
695 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400696}
697
David Benjamin1d77e562015-03-22 17:22:08 -0400698static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400699 const uint8_t *cptr;
700 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400701
David Benjamin1d77e562015-03-22 17:22:08 -0400702 // Decode the input.
703 std::vector<uint8_t> input;
704 if (!DecodeBase64(&input, input_b64)) {
705 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400706 }
707
David Benjamin1d77e562015-03-22 17:22:08 -0400708 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700709 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400710 if (!session) {
711 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400712 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400713 }
714
David Benjamin1d77e562015-03-22 17:22:08 -0400715 // Verify the SSL_SESSION encoding round-trips.
716 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700717 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400718 uint8_t *encoded_raw;
719 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400720 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400721 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400722 }
David Benjamin1d77e562015-03-22 17:22:08 -0400723 encoded.reset(encoded_raw);
724 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800725 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400726 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200727 hexdump(stderr, "Before: ", input.data(), input.size());
728 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400729 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400730 }
David Benjamin3cac4502014-10-21 01:46:30 -0400731
David Benjaminfd67aa82015-06-15 19:41:48 -0400732 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800733 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400734 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800735 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400736 fprintf(stderr, "d2i_SSL_SESSION failed\n");
737 return false;
738 }
739
David Benjamin1d77e562015-03-22 17:22:08 -0400740 // Verify the SSL_SESSION encoding round-trips via the legacy API.
741 int len = i2d_SSL_SESSION(session.get(), NULL);
742 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400743 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400744 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400745 }
746
David Benjamin1d77e562015-03-22 17:22:08 -0400747 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
748 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400749 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400750 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400751 }
David Benjamin1d77e562015-03-22 17:22:08 -0400752
753 ptr = encoded.get();
754 len = i2d_SSL_SESSION(session.get(), &ptr);
755 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400756 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400757 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400758 }
David Benjamin1d77e562015-03-22 17:22:08 -0400759 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400760 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400761 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400762 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800763 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400764 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400765 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400766 }
767
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400769}
770
David Benjaminf297e022015-05-28 19:55:29 -0400771static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
772 std::vector<uint8_t> input;
773 if (!DecodeBase64(&input, input_b64)) {
774 return false;
775 }
776
777 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700778 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400779 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400780 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400781 return false;
782 }
783 ERR_clear_error();
784 return true;
785}
786
David Benjamin10e664b2016-06-20 22:20:47 -0400787static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400788 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700789 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400790 if (!ctx) {
791 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500792 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400793 if (ctx->min_version != min_version || ctx->max_version != max_version) {
794 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
795 ctx->min_version, ctx->max_version, min_version, max_version);
796 return false;
797 }
798 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500799}
800
David Benjamin1d77e562015-03-22 17:22:08 -0400801static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500802 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
803 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400804 return false;
David Benjamin65226252015-02-05 16:49:47 -0500805 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700806 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400807 if (!rfc_name) {
808 return false;
809 }
David Benjamin67be0482015-04-20 16:19:00 -0400810 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400811 return true;
David Benjamin65226252015-02-05 16:49:47 -0500812}
813
814typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500815 int id;
David Benjamin65226252015-02-05 16:49:47 -0500816 const char *rfc_name;
817} CIPHER_RFC_NAME_TEST;
818
819static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400820 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
821 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
822 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
823 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
824 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
825 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
826 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
827 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
828 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
829 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
830 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
831 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
832 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
833 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
834 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
835 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
836 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
837 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
838 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
839 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
840 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
841 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
842
843 // These names are non-standard:
844 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
845 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
846 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
847 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500848};
849
David Benjamin1d77e562015-03-22 17:22:08 -0400850static bool TestCipherGetRFCName(void) {
851 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400852 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500853 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400854 std::string rfc_name;
855 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
856 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
857 return false;
David Benjamin65226252015-02-05 16:49:47 -0500858 }
David Benjamin1d77e562015-03-22 17:22:08 -0400859 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500860 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400861 rfc_name.c_str(), test->rfc_name);
862 return false;
David Benjamin65226252015-02-05 16:49:47 -0500863 }
David Benjamin65226252015-02-05 16:49:47 -0500864 }
David Benjamin1d77e562015-03-22 17:22:08 -0400865 return true;
David Benjamin65226252015-02-05 16:49:47 -0500866}
867
Steven Valdeza833c352016-11-01 13:39:36 -0400868// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
869// version and ticket length or nullptr on failure.
870static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
871 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400872 std::vector<uint8_t> der;
873 if (!DecodeBase64(&der, kOpenSSLSession)) {
874 return nullptr;
875 }
Steven Valdeza833c352016-11-01 13:39:36 -0400876 bssl::UniquePtr<SSL_SESSION> session(
877 SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400878 if (!session) {
879 return nullptr;
880 }
881
Steven Valdeza833c352016-11-01 13:39:36 -0400882 session->ssl_version = version;
883
David Benjamin422fe082015-07-21 22:03:43 -0400884 // Swap out the ticket for a garbage one.
885 OPENSSL_free(session->tlsext_tick);
886 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
887 if (session->tlsext_tick == nullptr) {
888 return nullptr;
889 }
890 memset(session->tlsext_tick, 'a', ticket_len);
891 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400892
893 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500894#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
895 session->time = 1234;
896#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400897 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500898#endif
David Benjamin422fe082015-07-21 22:03:43 -0400899 return session;
900}
901
David Benjaminafc64de2016-07-19 17:12:41 +0200902static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700903 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200904 if (!bio) {
905 return false;
906 }
907 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400908 BIO_up_ref(bio.get());
909 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200910 int ret = SSL_connect(ssl);
911 if (ret > 0) {
912 // SSL_connect should fail without a BIO to write to.
913 return false;
914 }
915 ERR_clear_error();
916
917 const uint8_t *client_hello;
918 size_t client_hello_len;
919 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
920 return false;
921 }
922 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
923 return true;
924}
925
Steven Valdeza833c352016-11-01 13:39:36 -0400926// GetClientHelloLen creates a client SSL connection with the specified version
927// and ticket length. It returns the length of the ClientHello, not including
928// the record header, on success and zero on error.
929static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
930 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700931 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400932 bssl::UniquePtr<SSL_SESSION> session =
933 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400934 if (!ctx || !session) {
935 return 0;
936 }
Steven Valdeza833c352016-11-01 13:39:36 -0400937
938 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700939 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400940 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400941 !SSL_set_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
942 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400943 return 0;
944 }
Steven Valdeza833c352016-11-01 13:39:36 -0400945
David Benjaminafc64de2016-07-19 17:12:41 +0200946 std::vector<uint8_t> client_hello;
947 if (!GetClientHello(ssl.get(), &client_hello) ||
948 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400949 return 0;
950 }
Steven Valdeza833c352016-11-01 13:39:36 -0400951
David Benjaminafc64de2016-07-19 17:12:41 +0200952 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400953}
954
955struct PaddingTest {
956 size_t input_len, padded_len;
957};
958
959static const PaddingTest kPaddingTests[] = {
960 // ClientHellos of length below 0x100 do not require padding.
961 {0xfe, 0xfe},
962 {0xff, 0xff},
963 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
964 {0x100, 0x200},
965 {0x123, 0x200},
966 {0x1fb, 0x200},
967 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
968 // padding extension takes a minimum of four bytes plus one required content
969 // byte. (To work around yet more server bugs, we avoid empty final
970 // extensions.)
971 {0x1fc, 0x201},
972 {0x1fd, 0x202},
973 {0x1fe, 0x203},
974 {0x1ff, 0x204},
975 // Finally, larger ClientHellos need no padding.
976 {0x200, 0x200},
977 {0x201, 0x201},
978};
979
Steven Valdeza833c352016-11-01 13:39:36 -0400980static bool TestPaddingExtension(uint16_t max_version,
981 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400982 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400983 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400984 if (base_len == 0) {
985 return false;
986 }
987
988 for (const PaddingTest &test : kPaddingTests) {
989 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400990 fprintf(stderr,
991 "Baseline ClientHello too long (max_version = %04x, "
992 "session_version = %04x).\n",
993 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400994 return false;
995 }
996
Steven Valdeza833c352016-11-01 13:39:36 -0400997 size_t padded_len = GetClientHelloLen(max_version, session_version,
998 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400999 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001000 fprintf(stderr,
1001 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1002 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001003 static_cast<unsigned>(test.input_len),
1004 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001005 static_cast<unsigned>(test.padded_len), max_version,
1006 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001007 return false;
1008 }
1009 }
Steven Valdeza833c352016-11-01 13:39:36 -04001010
David Benjamin422fe082015-07-21 22:03:43 -04001011 return true;
1012}
1013
David Benjamin1d128f32015-09-08 17:41:40 -04001014// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1015// before configuring as a server.
1016static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001017 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -04001018 if (!ctx) {
1019 return false;
1020 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001021 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -04001022 if (!ssl) {
1023 return false;
1024 }
1025
1026 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
1027 if (stack == nullptr) {
1028 return false;
1029 }
1030 // |SSL_set_client_CA_list| takes ownership.
1031 SSL_set_client_CA_list(ssl.get(), stack);
1032
1033 return SSL_get_client_CA_list(ssl.get()) == stack;
1034}
1035
David Benjamin0f653952015-10-18 14:28:01 -04001036static void AppendSession(SSL_SESSION *session, void *arg) {
1037 std::vector<SSL_SESSION*> *out =
1038 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1039 out->push_back(session);
1040}
1041
1042// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1043// order.
1044static bool ExpectCache(SSL_CTX *ctx,
1045 const std::vector<SSL_SESSION*> &expected) {
1046 // Check the linked list.
1047 SSL_SESSION *ptr = ctx->session_cache_head;
1048 for (SSL_SESSION *session : expected) {
1049 if (ptr != session) {
1050 return false;
1051 }
1052 // TODO(davidben): This is an absurd way to denote the end of the list.
1053 if (ptr->next ==
1054 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1055 ptr = nullptr;
1056 } else {
1057 ptr = ptr->next;
1058 }
1059 }
1060 if (ptr != nullptr) {
1061 return false;
1062 }
1063
1064 // Check the hash table.
1065 std::vector<SSL_SESSION*> actual, expected_copy;
1066 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1067 expected_copy = expected;
1068
1069 std::sort(actual.begin(), actual.end());
1070 std::sort(expected_copy.begin(), expected_copy.end());
1071
1072 return actual == expected_copy;
1073}
1074
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001075static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1076 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001077 if (!ret) {
1078 return nullptr;
1079 }
1080
1081 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1082 memset(ret->session_id, 0, ret->session_id_length);
1083 memcpy(ret->session_id, &number, sizeof(number));
1084 return ret;
1085}
1086
David Benjamin0f653952015-10-18 14:28:01 -04001087// Test that the internal session cache behaves as expected.
1088static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001089 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001090 if (!ctx) {
1091 return false;
1092 }
1093
1094 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001095 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001096 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001097 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001098 if (!session) {
1099 return false;
1100 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001101 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001102 }
1103
1104 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1105
1106 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001107 for (const auto &session : sessions) {
1108 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001109 return false;
1110 }
1111 }
1112
1113 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001114 std::vector<SSL_SESSION*> expected = {
1115 sessions[9].get(),
1116 sessions[8].get(),
1117 sessions[7].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 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001126 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001127 !ExpectCache(ctx.get(), expected)) {
1128 return false;
1129 }
1130
1131 // Although collisions should be impossible (256-bit session IDs), the cache
1132 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001133 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001134 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1135 return false;
1136 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001137 expected = {
1138 collision.get(),
1139 sessions[9].get(),
1140 sessions[8].get(),
1141 sessions[6].get(),
1142 sessions[5].get(),
1143 };
David Benjamin0f653952015-10-18 14:28:01 -04001144 if (!ExpectCache(ctx.get(), expected)) {
1145 return false;
1146 }
1147
1148 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001149 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001150 return false;
1151 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001152 expected = {
1153 collision.get(),
1154 sessions[9].get(),
1155 sessions[8].get(),
1156 sessions[5].get(),
1157 };
David Benjamin0f653952015-10-18 14:28:01 -04001158 if (!ExpectCache(ctx.get(), expected)) {
1159 return false;
1160 }
1161
1162 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001163 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1164 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001165 !ExpectCache(ctx.get(), expected)) {
1166 return false;
1167 }
1168
1169 return true;
1170}
1171
David Benjaminde942382016-02-11 12:02:01 -05001172static uint16_t EpochFromSequence(uint64_t seq) {
1173 return static_cast<uint16_t>(seq >> 48);
1174}
1175
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001176static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001177 static const char kCertPEM[] =
1178 "-----BEGIN CERTIFICATE-----\n"
1179 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1180 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1181 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1182 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1183 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1184 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1185 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1186 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1187 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1188 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1189 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1190 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1191 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1192 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001193 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1194 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001195}
1196
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001197static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001198 static const char kKeyPEM[] =
1199 "-----BEGIN RSA PRIVATE KEY-----\n"
1200 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1201 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1202 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1203 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1204 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1205 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1206 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1207 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1208 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1209 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1210 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1211 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1212 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1213 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001214 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1215 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001216 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1217}
1218
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001219static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001220 static const char kCertPEM[] =
1221 "-----BEGIN CERTIFICATE-----\n"
1222 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1223 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1224 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1225 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1226 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1227 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1228 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1229 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1230 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1231 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1232 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001233 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1234 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001235}
1236
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001237static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001238 static const char kKeyPEM[] =
1239 "-----BEGIN PRIVATE KEY-----\n"
1240 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1241 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1242 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1243 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001244 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1245 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001246 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1247}
1248
David Benjaminb79cc842016-12-07 15:57:14 -05001249static bool CompleteHandshakes(SSL *client, SSL *server) {
1250 // Drive both their handshakes to completion.
1251 for (;;) {
1252 int client_ret = SSL_do_handshake(client);
1253 int client_err = SSL_get_error(client, client_ret);
1254 if (client_err != SSL_ERROR_NONE &&
1255 client_err != SSL_ERROR_WANT_READ &&
1256 client_err != SSL_ERROR_WANT_WRITE) {
1257 fprintf(stderr, "Client error: %d\n", client_err);
1258 return false;
1259 }
1260
1261 int server_ret = SSL_do_handshake(server);
1262 int server_err = SSL_get_error(server, server_ret);
1263 if (server_err != SSL_ERROR_NONE &&
1264 server_err != SSL_ERROR_WANT_READ &&
1265 server_err != SSL_ERROR_WANT_WRITE) {
1266 fprintf(stderr, "Server error: %d\n", server_err);
1267 return false;
1268 }
1269
1270 if (client_ret == 1 && server_ret == 1) {
1271 break;
1272 }
1273 }
1274
1275 return true;
1276}
1277
1278static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1279 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001280 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1281 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001282 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001283 if (!client || !server) {
1284 return false;
1285 }
1286 SSL_set_connect_state(client.get());
1287 SSL_set_accept_state(server.get());
1288
David Benjamina20e5352016-08-02 19:09:41 -04001289 SSL_set_session(client.get(), session);
1290
David Benjaminde942382016-02-11 12:02:01 -05001291 BIO *bio1, *bio2;
1292 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1293 return false;
1294 }
1295 // SSL_set_bio takes ownership.
1296 SSL_set_bio(client.get(), bio1, bio1);
1297 SSL_set_bio(server.get(), bio2, bio2);
1298
David Benjaminb79cc842016-12-07 15:57:14 -05001299 if (!CompleteHandshakes(client.get(), server.get())) {
1300 return false;
David Benjaminde942382016-02-11 12:02:01 -05001301 }
1302
David Benjamin686bb192016-05-10 15:15:41 -04001303 *out_client = std::move(client);
1304 *out_server = std::move(server);
1305 return true;
1306}
1307
David Benjamin0fef3052016-11-18 15:11:10 +09001308static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1309 uint16_t version) {
1310 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1311 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1312 if (!server_ctx || !client_ctx ||
1313 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1314 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1315 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1316 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1317 return false;
1318 }
David Benjamin686bb192016-05-10 15:15:41 -04001319
David Benjamin0fef3052016-11-18 15:11:10 +09001320 bssl::UniquePtr<X509> cert = GetTestCertificate();
1321 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1322 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1323 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1324 return false;
1325 }
David Benjamin686bb192016-05-10 15:15:41 -04001326
David Benjamin0fef3052016-11-18 15:11:10 +09001327 bssl::UniquePtr<SSL> client, server;
1328 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1329 server_ctx.get(), nullptr /* no session */)) {
1330 return false;
1331 }
David Benjamin686bb192016-05-10 15:15:41 -04001332
David Benjamin0fef3052016-11-18 15:11:10 +09001333 // Drain any post-handshake messages to ensure there are no unread records
1334 // on either end.
1335 uint8_t byte = 0;
1336 if (SSL_read(client.get(), &byte, 1) > 0 ||
1337 SSL_read(server.get(), &byte, 1) > 0) {
1338 fprintf(stderr, "Received unexpected data.\n");
1339 return false;
1340 }
David Benjaminde942382016-02-11 12:02:01 -05001341
David Benjamin0fef3052016-11-18 15:11:10 +09001342 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1343 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1344 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1345 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001346
David Benjamin0fef3052016-11-18 15:11:10 +09001347 if (is_dtls) {
1348 // Both client and server must be at epoch 1.
1349 if (EpochFromSequence(client_read_seq) != 1 ||
1350 EpochFromSequence(client_write_seq) != 1 ||
1351 EpochFromSequence(server_read_seq) != 1 ||
1352 EpochFromSequence(server_write_seq) != 1) {
1353 fprintf(stderr, "Bad epochs.\n");
1354 return false;
David Benjaminde942382016-02-11 12:02:01 -05001355 }
David Benjamin0fef3052016-11-18 15:11:10 +09001356
1357 // The next record to be written should exceed the largest received.
1358 if (client_write_seq <= server_read_seq ||
1359 server_write_seq <= client_read_seq) {
1360 fprintf(stderr, "Inconsistent sequence numbers.\n");
1361 return false;
1362 }
1363 } else {
1364 // The next record to be written should equal the next to be received.
1365 if (client_write_seq != server_read_seq ||
1366 server_write_seq != client_read_seq) {
1367 fprintf(stderr, "Inconsistent sequence numbers.\n");
1368 return false;
1369 }
1370 }
1371
1372 // Send a record from client to server.
1373 if (SSL_write(client.get(), &byte, 1) != 1 ||
1374 SSL_read(server.get(), &byte, 1) != 1) {
1375 fprintf(stderr, "Could not send byte.\n");
1376 return false;
1377 }
1378
1379 // The client write and server read sequence numbers should have
1380 // incremented.
1381 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1382 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1383 fprintf(stderr, "Sequence numbers did not increment.\n");
1384 return false;
David Benjaminde942382016-02-11 12:02:01 -05001385 }
1386
1387 return true;
1388}
1389
David Benjamin68f37b72016-11-18 15:14:42 +09001390static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1391 uint16_t version) {
1392 // SSL_shutdown is a no-op in DTLS.
1393 if (is_dtls) {
1394 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001395 }
1396
David Benjamin68f37b72016-11-18 15:14:42 +09001397 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1398 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001399 bssl::UniquePtr<X509> cert = GetTestCertificate();
1400 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001401 if (!client_ctx || !server_ctx || !cert || !key ||
1402 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1403 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1404 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1405 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001406 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1407 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1408 return false;
1409 }
1410
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001411 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001412 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001413 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001414 return false;
1415 }
1416
1417 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1418 // one side has shut down.
1419 if (SSL_shutdown(client.get()) != 0) {
1420 fprintf(stderr, "Could not shutdown.\n");
1421 return false;
1422 }
1423
1424 // Reading from the server should consume the EOF.
1425 uint8_t byte;
1426 if (SSL_read(server.get(), &byte, 1) != 0 ||
1427 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1428 fprintf(stderr, "Connection was not shut down cleanly.\n");
1429 return false;
1430 }
1431
1432 // However, the server may continue to write data and then shut down the
1433 // connection.
1434 byte = 42;
1435 if (SSL_write(server.get(), &byte, 1) != 1 ||
1436 SSL_read(client.get(), &byte, 1) != 1 ||
1437 byte != 42) {
1438 fprintf(stderr, "Could not send byte.\n");
1439 return false;
1440 }
1441
1442 // The server may then shutdown the connection.
1443 if (SSL_shutdown(server.get()) != 1 ||
1444 SSL_shutdown(client.get()) != 1) {
1445 fprintf(stderr, "Could not complete shutdown.\n");
1446 return false;
1447 }
1448
1449 return true;
1450}
David Benjamin68f37b72016-11-18 15:14:42 +09001451
Steven Valdez87eab492016-06-27 16:34:59 -04001452static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001453 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1454 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001455 if (!client_ctx || !server_ctx) {
1456 return false;
1457 }
1458
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001459 bssl::UniquePtr<X509> cert = GetTestCertificate();
1460 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001461 if (!cert || !key ||
1462 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1463 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1464 return false;
1465 }
1466
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001467 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001468 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001469 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001470 return false;
1471 }
1472
1473 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001474 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001475 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001476 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001477 }
David Benjamin4501bd52016-08-01 13:39:41 -04001478
Steven Valdez84b5c002016-08-25 16:30:58 -04001479 session1->not_resumable = 0;
1480
Steven Valdez87eab492016-06-27 16:34:59 -04001481 uint8_t *s0_bytes, *s1_bytes;
1482 size_t s0_len, s1_len;
1483
1484 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1485 return false;
1486 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001487 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001488
1489 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1490 return false;
1491 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001492 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001493
1494 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1495}
David Benjamin686bb192016-05-10 15:15:41 -04001496
David Benjamin5c0fb882016-06-14 14:03:51 -04001497static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1498 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1499 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1500 SSL_get_wfd(ssl), rfd, wfd);
1501 return false;
1502 }
1503
1504 // The wrapper BIOs are always equal when fds are equal, even if set
1505 // individually.
1506 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1507 fprintf(stderr, "rbio and wbio did not match.\n");
1508 return false;
1509 }
1510
1511 return true;
1512}
1513
1514static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001515 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001516 if (!ctx) {
1517 return false;
1518 }
1519
1520 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001521 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001522 if (!ssl ||
1523 !SSL_set_rfd(ssl.get(), 1) ||
1524 !SSL_set_wfd(ssl.get(), 2) ||
1525 !ExpectFDs(ssl.get(), 1, 2)) {
1526 return false;
1527 }
1528
1529 // Test setting the same FD.
1530 ssl.reset(SSL_new(ctx.get()));
1531 if (!ssl ||
1532 !SSL_set_fd(ssl.get(), 1) ||
1533 !ExpectFDs(ssl.get(), 1, 1)) {
1534 return false;
1535 }
1536
1537 // Test setting the same FD one side at a time.
1538 ssl.reset(SSL_new(ctx.get()));
1539 if (!ssl ||
1540 !SSL_set_rfd(ssl.get(), 1) ||
1541 !SSL_set_wfd(ssl.get(), 1) ||
1542 !ExpectFDs(ssl.get(), 1, 1)) {
1543 return false;
1544 }
1545
1546 // Test setting the same FD in the other order.
1547 ssl.reset(SSL_new(ctx.get()));
1548 if (!ssl ||
1549 !SSL_set_wfd(ssl.get(), 1) ||
1550 !SSL_set_rfd(ssl.get(), 1) ||
1551 !ExpectFDs(ssl.get(), 1, 1)) {
1552 return false;
1553 }
1554
David Benjamin5c0fb882016-06-14 14:03:51 -04001555 // Test changing the read FD partway through.
1556 ssl.reset(SSL_new(ctx.get()));
1557 if (!ssl ||
1558 !SSL_set_fd(ssl.get(), 1) ||
1559 !SSL_set_rfd(ssl.get(), 2) ||
1560 !ExpectFDs(ssl.get(), 2, 1)) {
1561 return false;
1562 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001563
1564 // Test changing the write FD partway through.
1565 ssl.reset(SSL_new(ctx.get()));
1566 if (!ssl ||
1567 !SSL_set_fd(ssl.get(), 1) ||
1568 !SSL_set_wfd(ssl.get(), 2) ||
1569 !ExpectFDs(ssl.get(), 1, 2)) {
1570 return false;
1571 }
1572
1573 // Test a no-op change to the read FD partway through.
1574 ssl.reset(SSL_new(ctx.get()));
1575 if (!ssl ||
1576 !SSL_set_fd(ssl.get(), 1) ||
1577 !SSL_set_rfd(ssl.get(), 1) ||
1578 !ExpectFDs(ssl.get(), 1, 1)) {
1579 return false;
1580 }
1581
1582 // Test a no-op change to the write FD partway through.
1583 ssl.reset(SSL_new(ctx.get()));
1584 if (!ssl ||
1585 !SSL_set_fd(ssl.get(), 1) ||
1586 !SSL_set_wfd(ssl.get(), 1) ||
1587 !ExpectFDs(ssl.get(), 1, 1)) {
1588 return false;
1589 }
1590
1591 // ASan builds will implicitly test that the internal |BIO| reference-counting
1592 // is correct.
1593
1594 return true;
1595}
1596
David Benjamin4501bd52016-08-01 13:39:41 -04001597static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001598 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001599 if (!ctx) {
1600 return false;
1601 }
1602
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001603 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1604 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001605 bio3(BIO_new(BIO_s_mem()));
1606 if (!ssl || !bio1 || !bio2 || !bio3) {
1607 return false;
1608 }
1609
1610 // SSL_set_bio takes one reference when the parameters are the same.
1611 BIO_up_ref(bio1.get());
1612 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1613
1614 // Repeating the call does nothing.
1615 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1616
1617 // It takes one reference each when the parameters are different.
1618 BIO_up_ref(bio2.get());
1619 BIO_up_ref(bio3.get());
1620 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1621
1622 // Repeating the call does nothing.
1623 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1624
1625 // It takes one reference when changing only wbio.
1626 BIO_up_ref(bio1.get());
1627 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1628
1629 // It takes one reference when changing only rbio and the two are different.
1630 BIO_up_ref(bio3.get());
1631 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1632
1633 // If setting wbio to rbio, it takes no additional references.
1634 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1635
1636 // From there, wbio may be switched to something else.
1637 BIO_up_ref(bio1.get());
1638 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1639
1640 // If setting rbio to wbio, it takes no additional references.
1641 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1642
1643 // From there, rbio may be switched to something else, but, for historical
1644 // reasons, it takes a reference to both parameters.
1645 BIO_up_ref(bio1.get());
1646 BIO_up_ref(bio2.get());
1647 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1648
1649 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1650 // is correct.
1651 return true;
1652}
1653
David Benjamin25490f22016-07-14 00:22:54 -04001654static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1655
David Benjamin0fef3052016-11-18 15:11:10 +09001656static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1657 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001658 bssl::UniquePtr<X509> cert = GetTestCertificate();
1659 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001660 if (!cert || !key) {
1661 return false;
1662 }
1663
David Benjamin0fef3052016-11-18 15:11:10 +09001664 // Configure both client and server to accept any certificate.
1665 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1666 if (!ctx ||
1667 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1668 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1669 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1670 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1671 return false;
1672 }
1673 SSL_CTX_set_verify(
1674 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1675 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001676
David Benjamin0fef3052016-11-18 15:11:10 +09001677 bssl::UniquePtr<SSL> client, server;
1678 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1679 nullptr /* no session */)) {
1680 return false;
1681 }
David Benjaminadd5e522016-07-14 00:33:24 -04001682
David Benjamin0fef3052016-11-18 15:11:10 +09001683 // Client and server should both see the leaf certificate.
1684 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1685 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1686 fprintf(stderr, "Server peer certificate did not match.\n");
1687 return false;
1688 }
David Benjaminadd5e522016-07-14 00:33:24 -04001689
David Benjamin0fef3052016-11-18 15:11:10 +09001690 peer.reset(SSL_get_peer_certificate(client.get()));
1691 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1692 fprintf(stderr, "Client peer certificate did not match.\n");
1693 return false;
1694 }
David Benjaminadd5e522016-07-14 00:33:24 -04001695
David Benjamin0fef3052016-11-18 15:11:10 +09001696 // However, for historical reasons, the chain includes the leaf on the
1697 // client, but does not on the server.
1698 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1699 fprintf(stderr, "Client peer chain was incorrect.\n");
1700 return false;
1701 }
David Benjaminadd5e522016-07-14 00:33:24 -04001702
David Benjamin0fef3052016-11-18 15:11:10 +09001703 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1704 fprintf(stderr, "Server peer chain was incorrect.\n");
1705 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001706 }
1707
1708 return true;
1709}
1710
David Benjamin0fef3052016-11-18 15:11:10 +09001711static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1712 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001713 bssl::UniquePtr<X509> cert = GetTestCertificate();
1714 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001715 if (!cert || !key) {
1716 return false;
1717 }
1718
1719 uint8_t *cert_der = NULL;
1720 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1721 if (cert_der_len < 0) {
1722 return false;
1723 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001724 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001725
1726 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1727 SHA256(cert_der, cert_der_len, cert_sha256);
1728
David Benjamin0fef3052016-11-18 15:11:10 +09001729 // Configure both client and server to accept any certificate, but the
1730 // server must retain only the SHA-256 of the peer.
1731 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1732 if (!ctx ||
1733 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1734 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1735 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1736 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1737 return false;
1738 }
1739 SSL_CTX_set_verify(
1740 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1741 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1742 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001743
David Benjamin0fef3052016-11-18 15:11:10 +09001744 bssl::UniquePtr<SSL> client, server;
1745 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1746 nullptr /* no session */)) {
1747 return false;
1748 }
David Benjamin25490f22016-07-14 00:22:54 -04001749
David Benjamin0fef3052016-11-18 15:11:10 +09001750 // The peer certificate has been dropped.
1751 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1752 if (peer) {
1753 fprintf(stderr, "Peer certificate was retained.\n");
1754 return false;
1755 }
David Benjamin25490f22016-07-14 00:22:54 -04001756
David Benjamin0fef3052016-11-18 15:11:10 +09001757 SSL_SESSION *session = SSL_get_session(server.get());
1758 if (!session->peer_sha256_valid) {
1759 fprintf(stderr, "peer_sha256_valid was not set.\n");
1760 return false;
1761 }
David Benjamin25490f22016-07-14 00:22:54 -04001762
David Benjamin0fef3052016-11-18 15:11:10 +09001763 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1764 fprintf(stderr, "peer_sha256 did not match.\n");
1765 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001766 }
1767
1768 return true;
1769}
1770
David Benjaminafc64de2016-07-19 17:12:41 +02001771static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1772 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001773 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001774 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001775 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001776 // Our default cipher list varies by CPU capabilities, so manually place
1777 // the ChaCha20 ciphers in front.
1778 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001779 return false;
1780 }
David Benjamin2dc02042016-09-19 19:57:37 -04001781
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001782 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001783 if (!ssl) {
1784 return false;
1785 }
1786 std::vector<uint8_t> client_hello;
1787 if (!GetClientHello(ssl.get(), &client_hello)) {
1788 return false;
1789 }
1790
1791 // Zero the client_random.
1792 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1793 1 + 3 + // handshake message header
1794 2; // client_version
1795 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1796 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1797 return false;
1798 }
1799 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1800
1801 if (client_hello.size() != expected_len ||
1802 memcmp(client_hello.data(), expected, expected_len) != 0) {
1803 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1804 fprintf(stderr, "Got:\n\t");
1805 for (size_t i = 0; i < client_hello.size(); i++) {
1806 fprintf(stderr, "0x%02x, ", client_hello[i]);
1807 }
1808 fprintf(stderr, "\nWanted:\n\t");
1809 for (size_t i = 0; i < expected_len; i++) {
1810 fprintf(stderr, "0x%02x, ", expected[i]);
1811 }
1812 fprintf(stderr, "\n");
1813 return false;
1814 }
1815
1816 return true;
1817}
1818
1819// Tests that our ClientHellos do not change unexpectedly.
1820static bool TestClientHello() {
1821 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001822 0x16,
1823 0x03, 0x00,
1824 0x00, 0x3f,
1825 0x01,
1826 0x00, 0x00, 0x3b,
1827 0x03, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832 0x00,
1833 0x00, 0x14,
1834 0xc0, 0x09,
1835 0xc0, 0x13,
1836 0x00, 0x33,
1837 0xc0, 0x0a,
1838 0xc0, 0x14,
1839 0x00, 0x39,
1840 0x00, 0x2f,
1841 0x00, 0x35,
1842 0x00, 0x0a,
1843 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001844 };
1845 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1846 sizeof(kSSL3ClientHello))) {
1847 return false;
1848 }
1849
1850 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001851 0x16,
1852 0x03, 0x01,
1853 0x00, 0x5e,
1854 0x01,
1855 0x00, 0x00, 0x5a,
1856 0x03, 0x01,
1857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1861 0x00,
1862 0x00, 0x12,
1863 0xc0, 0x09,
1864 0xc0, 0x13,
1865 0x00, 0x33,
1866 0xc0, 0x0a,
1867 0xc0, 0x14,
1868 0x00, 0x39,
1869 0x00, 0x2f,
1870 0x00, 0x35,
1871 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001872 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1873 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1874 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1875 };
1876 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1877 sizeof(kTLS1ClientHello))) {
1878 return false;
1879 }
1880
1881 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001882 0x16,
1883 0x03, 0x01,
1884 0x00, 0x5e,
1885 0x01,
1886 0x00, 0x00, 0x5a,
1887 0x03, 0x02,
1888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1892 0x00,
1893 0x00, 0x12,
1894 0xc0, 0x09,
1895 0xc0, 0x13,
1896 0x00, 0x33,
1897 0xc0, 0x0a,
1898 0xc0, 0x14,
1899 0x00, 0x39,
1900 0x00, 0x2f,
1901 0x00, 0x35,
1902 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001903 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1904 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1905 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1906 };
1907 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1908 sizeof(kTLS11ClientHello))) {
1909 return false;
1910 }
1911
1912 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001913 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1917 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1918 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1919 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1920 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001921 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001922 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001923 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1924 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001925 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1926 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001927 };
1928 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1929 sizeof(kTLS12ClientHello))) {
1930 return false;
1931 }
1932
1933 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1934 // implementation has settled enough that it won't change.
1935
1936 return true;
1937}
1938
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001939static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001940
1941static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1942 // Save the most recent session.
1943 g_last_session.reset(session);
1944 return 1;
1945}
1946
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001947static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001948 SSL_CTX *server_ctx) {
1949 g_last_session = nullptr;
1950 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1951
1952 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001953 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001954 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1955 nullptr /* no session */)) {
1956 fprintf(stderr, "Failed to connect client and server.\n");
1957 return nullptr;
1958 }
1959
1960 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1961 SSL_read(client.get(), nullptr, 0);
1962
1963 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1964
1965 if (!g_last_session) {
1966 fprintf(stderr, "Client did not receive a session.\n");
1967 return nullptr;
1968 }
1969 return std::move(g_last_session);
1970}
1971
1972static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1973 SSL_SESSION *session,
1974 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001975 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001976 if (!ConnectClientAndServer(&client, &server, client_ctx,
1977 server_ctx, session)) {
1978 fprintf(stderr, "Failed to connect client and server.\n");
1979 return false;
1980 }
1981
1982 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1983 fprintf(stderr, "Client and server were inconsistent.\n");
1984 return false;
1985 }
1986
1987 bool was_reused = !!SSL_session_reused(client.get());
1988 if (was_reused != reused) {
1989 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1990 was_reused ? "" : " not");
1991 return false;
1992 }
1993
1994 return true;
1995}
1996
David Benjamin3c51d9b2016-11-01 17:50:42 -04001997static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
1998 SSL_CTX *server_ctx,
1999 SSL_SESSION *session) {
2000 g_last_session = nullptr;
2001 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2002
2003 bssl::UniquePtr<SSL> client, server;
2004 if (!ConnectClientAndServer(&client, &server, client_ctx,
2005 server_ctx, session)) {
2006 fprintf(stderr, "Failed to connect client and server.\n");
2007 return nullptr;
2008 }
2009
2010 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2011 fprintf(stderr, "Client and server were inconsistent.\n");
2012 return nullptr;
2013 }
2014
2015 if (!SSL_session_reused(client.get())) {
2016 fprintf(stderr, "Session was not reused.\n");
2017 return nullptr;
2018 }
2019
2020 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2021 SSL_read(client.get(), nullptr, 0);
2022
2023 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2024
2025 if (!g_last_session) {
2026 fprintf(stderr, "Client did not receive a renewed session.\n");
2027 return nullptr;
2028 }
2029 return std::move(g_last_session);
2030}
2031
David Benjamina933c382016-10-28 00:10:03 -04002032static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2033 static const uint8_t kContext[] = {3};
2034
2035 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2036 return SSL_TLSEXT_ERR_ALERT_FATAL;
2037 }
2038
2039 return SSL_TLSEXT_ERR_OK;
2040}
2041
David Benjamin731058e2016-12-03 23:15:13 -05002042static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04002043 static const uint8_t kContext[] = {3};
2044
David Benjamin731058e2016-12-03 23:15:13 -05002045 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2046 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04002047 return -1;
2048 }
2049
2050 return 1;
2051}
2052
David Benjamin0fef3052016-11-18 15:11:10 +09002053static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2054 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002055 bssl::UniquePtr<X509> cert = GetTestCertificate();
2056 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002057 if (!cert || !key) {
2058 return false;
2059 }
2060
2061 static const uint8_t kContext1[] = {1};
2062 static const uint8_t kContext2[] = {2};
2063
David Benjamin0fef3052016-11-18 15:11:10 +09002064 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2065 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2066 if (!server_ctx || !client_ctx ||
2067 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2068 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2069 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2070 sizeof(kContext1)) ||
2071 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2072 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2073 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2074 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2075 return false;
2076 }
David Benjamina20e5352016-08-02 19:09:41 -04002077
David Benjamin0fef3052016-11-18 15:11:10 +09002078 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2079 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002080
David Benjamin0fef3052016-11-18 15:11:10 +09002081 bssl::UniquePtr<SSL_SESSION> session =
2082 CreateClientSession(client_ctx.get(), server_ctx.get());
2083 if (!session) {
2084 fprintf(stderr, "Error getting session.\n");
2085 return false;
2086 }
David Benjamina20e5352016-08-02 19:09:41 -04002087
David Benjamin0fef3052016-11-18 15:11:10 +09002088 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2089 true /* expect session reused */)) {
2090 fprintf(stderr, "Error resuming session.\n");
2091 return false;
2092 }
David Benjamina20e5352016-08-02 19:09:41 -04002093
David Benjamin0fef3052016-11-18 15:11:10 +09002094 // Change the session ID context.
2095 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2096 sizeof(kContext2))) {
2097 return false;
2098 }
David Benjamina20e5352016-08-02 19:09:41 -04002099
David Benjamin0fef3052016-11-18 15:11:10 +09002100 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2101 false /* expect session not reused */)) {
2102 fprintf(stderr, "Error connecting with a different context.\n");
2103 return false;
2104 }
David Benjamina933c382016-10-28 00:10:03 -04002105
David Benjamin0fef3052016-11-18 15:11:10 +09002106 // Change the session ID context back and install an SNI callback to switch
2107 // it.
2108 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2109 sizeof(kContext1))) {
2110 return false;
2111 }
David Benjamina933c382016-10-28 00:10:03 -04002112
David Benjamin0fef3052016-11-18 15:11:10 +09002113 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2114 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002115
David Benjamin0fef3052016-11-18 15:11:10 +09002116 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2117 false /* expect session not reused */)) {
2118 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2119 return false;
2120 }
David Benjamina933c382016-10-28 00:10:03 -04002121
David Benjamin0fef3052016-11-18 15:11:10 +09002122 // Switch the session ID context with the early callback instead.
2123 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2124 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2125 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002126
David Benjamin0fef3052016-11-18 15:11:10 +09002127 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2128 false /* expect session not reused */)) {
2129 fprintf(stderr,
2130 "Error connecting with a context switch on early callback.\n");
2131 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002132 }
2133
2134 return true;
2135}
2136
David Benjamin721e8b72016-08-03 13:13:17 -04002137static timeval g_current_time;
2138
2139static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2140 *out_clock = g_current_time;
2141}
2142
David Benjamin3c51d9b2016-11-01 17:50:42 -04002143static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2144 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2145 int encrypt) {
2146 static const uint8_t kZeros[16] = {0};
2147
2148 if (encrypt) {
2149 memcpy(key_name, kZeros, sizeof(kZeros));
2150 RAND_bytes(iv, 16);
2151 } else if (memcmp(key_name, kZeros, 16) != 0) {
2152 return 0;
2153 }
2154
2155 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2156 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2157 return -1;
2158 }
2159
2160 // Returning two from the callback in decrypt mode renews the
2161 // session in TLS 1.2 and below.
2162 return encrypt ? 1 : 2;
2163}
2164
David Benjamin123db572016-11-03 16:59:25 -04002165static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002166 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2167 return false;
2168 }
2169
David Benjamin123db572016-11-03 16:59:25 -04002170 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2171 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2172 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2173
David Benjamin9b63f292016-11-15 00:44:05 -05002174#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2175 // Fuzzer-mode tickets are unencrypted.
2176 memcpy(plaintext.get(), ciphertext, len);
2177#else
2178 static const uint8_t kZeros[16] = {0};
2179 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002180 bssl::ScopedEVP_CIPHER_CTX ctx;
2181 int len1, len2;
2182 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2183 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2184 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2185 return false;
2186 }
2187
2188 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002189#endif
David Benjamin123db572016-11-03 16:59:25 -04002190
2191 bssl::UniquePtr<SSL_SESSION> server_session(
2192 SSL_SESSION_from_bytes(plaintext.get(), len));
2193 if (!server_session) {
2194 return false;
2195 }
2196
2197 *out = server_session->time;
2198 return true;
2199}
2200
David Benjamin0fef3052016-11-18 15:11:10 +09002201static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2202 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002203 bssl::UniquePtr<X509> cert = GetTestCertificate();
2204 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002205 if (!cert || !key) {
2206 return false;
2207 }
2208
David Benjamin0fef3052016-11-18 15:11:10 +09002209 for (bool server_test : std::vector<bool>{false, true}) {
2210 static const int kStartTime = 1000;
2211 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002212
David Benjamin0fef3052016-11-18 15:11:10 +09002213 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2214 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2215 if (!server_ctx || !client_ctx ||
2216 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2217 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2218 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2219 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2220 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2221 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2222 return false;
2223 }
2224
2225 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2226 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2227
2228 // Both client and server must enforce session timeouts.
2229 if (server_test) {
2230 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2231 } else {
2232 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2233 }
2234
2235 // Configure a ticket callback which renews tickets.
2236 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2237
2238 bssl::UniquePtr<SSL_SESSION> session =
2239 CreateClientSession(client_ctx.get(), server_ctx.get());
2240 if (!session) {
2241 fprintf(stderr, "Error getting session.\n");
2242 return false;
2243 }
2244
2245 // Advance the clock just behind the timeout.
2246 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
2247
2248 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2249 true /* expect session reused */)) {
2250 fprintf(stderr, "Error resuming session.\n");
2251 return false;
2252 }
2253
2254 // Advance the clock one more second.
2255 g_current_time.tv_sec++;
2256
2257 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2258 false /* expect session not reused */)) {
2259 fprintf(stderr, "Error resuming session.\n");
2260 return false;
2261 }
2262
2263 // Rewind the clock to before the session was minted.
2264 g_current_time.tv_sec = kStartTime - 1;
2265
2266 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2267 false /* expect session not reused */)) {
2268 fprintf(stderr, "Error resuming session.\n");
2269 return false;
2270 }
2271
2272 // SSL 3.0 cannot renew sessions.
2273 if (version == SSL3_VERSION) {
2274 continue;
2275 }
2276
2277 // Renew the session 10 seconds before expiration.
2278 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2279 bssl::UniquePtr<SSL_SESSION> new_session =
2280 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2281 if (!new_session) {
2282 fprintf(stderr, "Error renewing session.\n");
2283 return false;
2284 }
2285
2286 // This new session is not the same object as before.
2287 if (session.get() == new_session.get()) {
2288 fprintf(stderr, "New and old sessions alias.\n");
2289 return false;
2290 }
2291
2292 // Check the sessions have timestamps measured from issuance.
2293 long session_time = 0;
2294 if (server_test) {
2295 if (!GetServerTicketTime(&session_time, new_session.get())) {
2296 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002297 return false;
2298 }
David Benjamin0fef3052016-11-18 15:11:10 +09002299 } else {
2300 session_time = new_session->time;
2301 }
David Benjamin721e8b72016-08-03 13:13:17 -04002302
David Benjamin0fef3052016-11-18 15:11:10 +09002303 if (session_time != g_current_time.tv_sec) {
2304 fprintf(stderr, "New session is not measured from issuance.\n");
2305 return false;
2306 }
David Benjamin721e8b72016-08-03 13:13:17 -04002307
David Benjamin0fef3052016-11-18 15:11:10 +09002308 // The new session is usable just before the old expiration.
2309 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2310 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2311 new_session.get(),
2312 true /* expect session reused */)) {
2313 fprintf(stderr, "Error resuming renewed session.\n");
2314 return false;
2315 }
David Benjamin721e8b72016-08-03 13:13:17 -04002316
David Benjamin0fef3052016-11-18 15:11:10 +09002317 // Renewal does not extend the lifetime, so it is not usable beyond the
2318 // old expiration.
2319 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2320 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2321 new_session.get(),
2322 false /* expect session not reused */)) {
2323 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2324 return false;
David Benjamin1b22f852016-10-27 16:36:32 -04002325 }
David Benjamin721e8b72016-08-03 13:13:17 -04002326 }
2327
2328 return true;
2329}
2330
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002331static int SetSessionTimeoutCallback(SSL *ssl, void *arg) {
2332 long timeout = *(long *) arg;
2333 SSL_set_session_timeout(ssl, timeout);
2334 return 1;
2335}
2336
2337static bool TestSessionTimeoutCertCallback(bool is_dtls,
2338 const SSL_METHOD *method,
2339 uint16_t version) {
2340 static const int kStartTime = 1000;
2341 g_current_time.tv_sec = kStartTime;
2342
2343 bssl::UniquePtr<X509> cert = GetTestCertificate();
2344 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2345 if (!cert || !key) {
2346 return false;
2347 }
2348
2349 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2350 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2351 if (!server_ctx || !client_ctx ||
2352 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2353 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2354 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2355 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2356 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2357 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2358 return false;
2359 }
2360
2361 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2362 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2363
2364 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2365
2366 long timeout = 25;
2367 SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
2368
2369 bssl::UniquePtr<SSL_SESSION> session =
2370 CreateClientSession(client_ctx.get(), server_ctx.get());
2371 if (!session) {
2372 fprintf(stderr, "Error getting session.\n");
2373 return false;
2374 }
2375
2376 // Advance the clock just behind the timeout.
2377 g_current_time.tv_sec += timeout - 1;
2378
2379 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2380 true /* expect session reused */)) {
2381 fprintf(stderr, "Error resuming session.\n");
2382 return false;
2383 }
2384
2385 // Advance the clock one more second.
2386 g_current_time.tv_sec++;
2387
2388 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2389 false /* expect session not reused */)) {
2390 fprintf(stderr, "Error resuming session.\n");
2391 return false;
2392 }
2393
2394 // Set session timeout to 0 to disable resumption.
2395 timeout = 0;
2396 g_current_time.tv_sec = kStartTime;
2397
2398 bssl::UniquePtr<SSL_SESSION> not_resumable_session =
2399 CreateClientSession(client_ctx.get(), server_ctx.get());
2400 if (!not_resumable_session) {
2401 fprintf(stderr, "Error getting session.\n");
2402 return false;
2403 }
2404
2405 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2406 not_resumable_session.get(),
2407 false /* expect session not reused */)) {
2408 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2409 return false;
2410 }
2411
2412 // Set both context and connection (via callback) default session timeout.
2413 // The connection one is the one that ends up being used.
2414 timeout = 25;
2415 g_current_time.tv_sec = kStartTime;
2416
2417 SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
2418
2419 bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
2420 CreateClientSession(client_ctx.get(), server_ctx.get());
2421 if (!ctx_and_cb_session) {
2422 fprintf(stderr, "Error getting session.\n");
2423 return false;
2424 }
2425
2426 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2427 ctx_and_cb_session.get(),
2428 true /* expect session reused */)) {
2429 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2430 return false;
2431 }
2432
2433 // Advance the clock just behind the timeout.
2434 g_current_time.tv_sec += timeout - 1;
2435
2436 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2437 ctx_and_cb_session.get(),
2438 true /* expect session reused */)) {
2439 fprintf(stderr, "Error resuming session.\n");
2440 return false;
2441 }
2442
2443 // Advance the clock one more second.
2444 g_current_time.tv_sec++;
2445
2446 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2447 ctx_and_cb_session.get(),
2448 false /* expect session not reused */)) {
2449 fprintf(stderr, "Error resuming session.\n");
2450 return false;
2451 }
2452
2453 return true;
2454}
2455
David Benjamin0fc37ef2016-08-17 15:29:46 -04002456static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2457 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2458 SSL_set_SSL_CTX(ssl, ctx);
2459 return SSL_TLSEXT_ERR_OK;
2460}
2461
David Benjamin0fef3052016-11-18 15:11:10 +09002462static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2463 uint16_t version) {
2464 // SSL 3.0 lacks extensions.
2465 if (version == SSL3_VERSION) {
2466 return true;
2467 }
2468
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002469 bssl::UniquePtr<X509> cert = GetTestCertificate();
2470 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2471 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2472 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002473 if (!cert || !key || !cert2 || !key2) {
2474 return false;
2475 }
2476
David Benjamin0fef3052016-11-18 15:11:10 +09002477 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2478 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002479
David Benjamin0fef3052016-11-18 15:11:10 +09002480 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2481 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2482 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2483 if (!server_ctx || !server_ctx2 || !client_ctx ||
2484 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2485 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2486 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2487 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2488 // Historically signing preferences would be lost in some cases with the
2489 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2490 // this doesn't happen when |version| is TLS 1.2, configure the private
2491 // key to only sign SHA-256.
2492 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2493 1) ||
2494 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2495 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2496 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2497 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2498 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2499 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2500 return false;
2501 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002502
David Benjamin0fef3052016-11-18 15:11:10 +09002503 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2504 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002505
David Benjamin0fef3052016-11-18 15:11:10 +09002506 bssl::UniquePtr<SSL> client, server;
2507 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2508 server_ctx.get(), nullptr)) {
2509 fprintf(stderr, "Handshake failed.\n");
2510 return false;
2511 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002512
David Benjamin0fef3052016-11-18 15:11:10 +09002513 // The client should have received |cert2|.
2514 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2515 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2516 fprintf(stderr, "Incorrect certificate received.\n");
2517 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518 }
2519
2520 return true;
2521}
2522
David Benjamin731058e2016-12-03 23:15:13 -05002523static int SetMaxVersion(const SSL_CLIENT_HELLO *client_hello) {
2524 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002525 return -1;
2526 }
2527
David Benjamin99620572016-08-30 00:35:36 -04002528 return 1;
2529}
2530
2531// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2532// maximum version.
2533static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002534 bssl::UniquePtr<X509> cert = GetTestCertificate();
2535 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2536 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2537 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002538 if (!cert || !key || !server_ctx || !client_ctx ||
2539 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002540 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002541 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2542 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002543 return false;
2544 }
2545
David Benjamin99620572016-08-30 00:35:36 -04002546 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2547
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002548 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002549 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2550 server_ctx.get(), nullptr)) {
2551 return false;
2552 }
2553
2554 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2555 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2556 return false;
2557 }
2558
2559 return true;
2560}
2561
David Benjamin2dc02042016-09-19 19:57:37 -04002562static bool TestSetVersion() {
2563 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2564 if (!ctx) {
2565 return false;
2566 }
2567
David Benjamine4706902016-09-20 15:12:23 -04002568 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2569 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2570 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2571 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002572 fprintf(stderr, "Could not set valid TLS version.\n");
2573 return false;
2574 }
2575
David Benjamine4706902016-09-20 15:12:23 -04002576 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2577 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2578 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2579 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2580 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2581 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002582 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2583 return false;
2584 }
2585
David Benjamine34bcc92016-09-21 16:53:09 -04002586 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2587 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2588 fprintf(stderr, "Could not set default TLS version.\n");
2589 return false;
2590 }
2591
2592 if (ctx->min_version != SSL3_VERSION ||
2593 ctx->max_version != TLS1_2_VERSION) {
2594 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2595 ctx->min_version, ctx->max_version);
2596 return false;
2597 }
2598
David Benjamin2dc02042016-09-19 19:57:37 -04002599 ctx.reset(SSL_CTX_new(DTLS_method()));
2600 if (!ctx) {
2601 return false;
2602 }
2603
David Benjamine4706902016-09-20 15:12:23 -04002604 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2605 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2606 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2607 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002608 fprintf(stderr, "Could not set valid DTLS version.\n");
2609 return false;
2610 }
2611
David Benjamine4706902016-09-20 15:12:23 -04002612 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2613 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2614 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2615 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2616 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2617 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2618 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2619 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002620 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2621 return false;
2622 }
2623
David Benjamine34bcc92016-09-21 16:53:09 -04002624 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2625 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2626 fprintf(stderr, "Could not set default DTLS version.\n");
2627 return false;
2628 }
2629
2630 if (ctx->min_version != TLS1_1_VERSION ||
2631 ctx->max_version != TLS1_2_VERSION) {
2632 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2633 ctx->min_version, ctx->max_version);
2634 return false;
2635 }
2636
David Benjamin2dc02042016-09-19 19:57:37 -04002637 return true;
2638}
2639
David Benjamin0fef3052016-11-18 15:11:10 +09002640static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2641 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002642 bssl::UniquePtr<X509> cert = GetTestCertificate();
2643 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2644 if (!cert || !key) {
2645 return false;
2646 }
2647
David Benjamin0fef3052016-11-18 15:11:10 +09002648 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2649 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2650 bssl::UniquePtr<SSL> client, server;
2651 if (!server_ctx || !client_ctx ||
2652 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2653 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2654 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2655 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2656 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2657 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2658 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2659 server_ctx.get(), nullptr /* no session */)) {
2660 fprintf(stderr, "Failed to connect.\n");
2661 return false;
2662 }
David Benjamincb18ac22016-09-27 14:09:15 -04002663
David Benjamin0fef3052016-11-18 15:11:10 +09002664 if (SSL_version(client.get()) != version ||
2665 SSL_version(server.get()) != version) {
2666 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2667 SSL_version(client.get()), SSL_version(server.get()), version);
2668 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002669 }
2670
2671 return true;
2672}
2673
David Benjamin9ef31f02016-10-31 18:01:13 -04002674// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2675// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002676static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2677 uint16_t version) {
2678 // SSL 3.0 lacks extensions.
2679 if (version == SSL3_VERSION) {
2680 return true;
2681 }
2682
David Benjamin9ef31f02016-10-31 18:01:13 -04002683 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2684
2685 bssl::UniquePtr<X509> cert = GetTestCertificate();
2686 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2687 if (!cert || !key) {
2688 return false;
2689 }
2690
David Benjamin0fef3052016-11-18 15:11:10 +09002691 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2692 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2693 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2694 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2695 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2696 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2697 0) {
2698 return false;
2699 }
2700
2701 // The ALPN callback does not fail the handshake on error, so have the
2702 // callback write a boolean.
2703 std::pair<uint16_t, bool> callback_state(version, false);
2704 SSL_CTX_set_alpn_select_cb(
2705 ctx.get(),
2706 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2707 unsigned in_len, void *arg) -> int {
2708 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2709 if (SSL_get_pending_cipher(ssl) != nullptr &&
2710 SSL_version(ssl) == state->first) {
2711 state->second = true;
2712 }
2713 return SSL_TLSEXT_ERR_NOACK;
2714 },
2715 &callback_state);
2716
2717 bssl::UniquePtr<SSL> client, server;
2718 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2719 nullptr /* no session */)) {
2720 return false;
2721 }
2722
2723 if (!callback_state.second) {
2724 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2725 return false;
2726 }
2727
2728 return true;
2729}
2730
David Benjaminb79cc842016-12-07 15:57:14 -05002731static bool TestSSLClearSessionResumption(bool is_dtls,
2732 const SSL_METHOD *method,
2733 uint16_t version) {
2734 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2735 // API pattern.
2736 if (version == TLS1_3_VERSION) {
2737 return true;
2738 }
2739
2740 bssl::UniquePtr<X509> cert = GetTestCertificate();
2741 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2742 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2743 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2744 if (!cert || !key || !server_ctx || !client_ctx ||
2745 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2746 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2747 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2748 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2749 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2750 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2751 return false;
2752 }
2753
2754 // Connect a client and a server.
2755 bssl::UniquePtr<SSL> client, server;
2756 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2757 server_ctx.get(), nullptr /* no session */)) {
2758 return false;
2759 }
2760
2761 if (SSL_session_reused(client.get()) ||
2762 SSL_session_reused(server.get())) {
2763 fprintf(stderr, "Session unexpectedly reused.\n");
2764 return false;
2765 }
2766
2767 // Reset everything.
2768 if (!SSL_clear(client.get()) ||
2769 !SSL_clear(server.get())) {
2770 fprintf(stderr, "SSL_clear failed.\n");
2771 return false;
2772 }
2773
2774 // Attempt to connect a second time.
2775 if (!CompleteHandshakes(client.get(), server.get())) {
2776 fprintf(stderr, "Could not reuse SSL objects.\n");
2777 return false;
2778 }
2779
2780 // |SSL_clear| should implicitly offer the previous session to the server.
2781 if (!SSL_session_reused(client.get()) ||
2782 !SSL_session_reused(server.get())) {
2783 fprintf(stderr, "Session was not reused in second try.\n");
2784 return false;
2785 }
2786
2787 return true;
2788}
2789
David Benjamin0fef3052016-11-18 15:11:10 +09002790static bool ForEachVersion(bool (*test_func)(bool is_dtls,
2791 const SSL_METHOD *method,
2792 uint16_t version)) {
2793 static uint16_t kTLSVersions[] = {
2794 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
2795 TLS1_2_VERSION, TLS1_3_VERSION,
2796 };
2797
2798 static uint16_t kDTLSVersions[] = {
2799 DTLS1_VERSION, DTLS1_2_VERSION,
2800 };
2801
David Benjamin9ef31f02016-10-31 18:01:13 -04002802 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09002803 if (!test_func(false, TLS_method(), version)) {
2804 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002805 return false;
2806 }
David Benjamin0fef3052016-11-18 15:11:10 +09002807 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002808
David Benjamin0fef3052016-11-18 15:11:10 +09002809 for (uint16_t version : kDTLSVersions) {
2810 if (!test_func(true, DTLS_method(), version)) {
2811 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002812 return false;
2813 }
2814 }
2815
2816 return true;
2817}
2818
David Benjamin1d128f32015-09-08 17:41:40 -04002819int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002820 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002821
Adam Langley10f97f32016-07-12 08:09:33 -07002822 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002823 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002824 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2825 !TestSSL_SESSIONEncoding(kCustomSession) ||
2826 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2827 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2828 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2829 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002830 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002831 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2832 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2833 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2834 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2835 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2836 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2837 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2838 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2839 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04002840 // Test the padding extension at TLS 1.2.
2841 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
2842 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
2843 // will be no PSK binder after the padding extension.
2844 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
2845 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
2846 // will be a PSK binder after the padding extension.
2847 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07002848 !TestClientCAList() ||
2849 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002850 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09002851 !ForEachVersion(TestOneSidedShutdown) ||
Steven Valdez87eab492016-06-27 16:34:59 -04002852 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002853 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002854 !TestSetBIO() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002855 !ForEachVersion(TestGetPeerCertificate) ||
2856 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04002857 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002858 !ForEachVersion(TestSessionIDContext) ||
2859 !ForEachVersion(TestSessionTimeout) ||
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002860 !ForEachVersion(TestSessionTimeoutCertCallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002861 !ForEachVersion(TestSNICallback) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002862 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002863 !TestSetVersion() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002864 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05002865 !ForEachVersion(TestALPNCipherAvailable) ||
2866 !ForEachVersion(TestSSLClearSessionResumption)) {
Brian Smith83a82982015-04-09 16:21:10 -10002867 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002868 return 1;
2869 }
2870
David Benjamin2e521212014-07-16 14:37:51 -04002871 printf("PASS\n");
2872 return 0;
2873}