blob: 33ef025d472e484c5a99d6ac3919993575648580 [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 Benjamin96628432017-01-19 19:05:47 -050024#include <gtest/gtest.h>
25
David Benjamin751e8892014-10-19 00:59:36 -040026#include <openssl/base64.h>
27#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040028#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040029#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050032#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040033#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037
Steven Valdez87eab492016-06-27 16:34:59 -040038#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040039#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020040#include "../crypto/test/test_util.h"
41
David Benjamin721e8b72016-08-03 13:13:17 -040042#if defined(OPENSSL_WINDOWS)
43/* Windows defines struct timeval in winsock2.h. */
44OPENSSL_MSVC_PRAGMA(warning(push, 3))
45#include <winsock2.h>
46OPENSSL_MSVC_PRAGMA(warning(pop))
47#else
48#include <sys/time.h>
49#endif
50
David Benjamin1d77e562015-03-22 17:22:08 -040051
52struct ExpectedCipher {
53 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040055};
David Benjaminbb0a17c2014-09-20 15:35:39 -040056
David Benjamin1d77e562015-03-22 17:22:08 -040057struct CipherTest {
58 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040059 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050060 // The list of expected ciphers, in order.
61 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040062};
David Benjaminbb0a17c2014-09-20 15:35:39 -040063
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010064struct CurveTest {
65 // The rule string to apply.
66 const char *rule;
67 // The list of expected curves, in order.
68 std::vector<uint16_t> expected;
69};
70
David Benjaminfb974e62015-12-16 19:34:22 -050071static const CipherTest kCipherTests[] = {
72 // Selecting individual ciphers should work.
73 {
74 "ECDHE-ECDSA-CHACHA20-POLY1305:"
75 "ECDHE-RSA-CHACHA20-POLY1305:"
76 "ECDHE-ECDSA-AES128-GCM-SHA256:"
77 "ECDHE-RSA-AES128-GCM-SHA256",
78 {
79 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050080 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050081 {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},
David Benjaminfb974e62015-12-16 19:34:22 -050094 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
95 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050096 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
97 },
98 },
99 // ! banishes ciphers from future selections.
100 {
101 "!aRSA:"
102 "ECDHE-ECDSA-CHACHA20-POLY1305:"
103 "ECDHE-RSA-CHACHA20-POLY1305:"
104 "ECDHE-ECDSA-AES128-GCM-SHA256:"
105 "ECDHE-RSA-AES128-GCM-SHA256",
106 {
107 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500108 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // Multiple masks can be ANDed in a single rule.
112 {
113 "kRSA+AESGCM+AES128",
114 {
115 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
117 },
118 // - removes selected ciphers, but preserves their order for future
119 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
120 // ECDHE_RSA.
121 {
122 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
123 "AESGCM+AES128+aRSA",
124 {
125 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
126 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Unknown selectors are no-ops.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256:"
136 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500139 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500140 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
142 },
143 },
144 // Square brackets specify equi-preference groups.
145 {
146 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
147 "[ECDHE-RSA-CHACHA20-POLY1305]:"
148 "ECDHE-RSA-AES128-GCM-SHA256",
149 {
150 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500151 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800152 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500153 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
154 },
155 },
156 // @STRENGTH performs a stable strength-sort of the selected ciphers and
157 // only the selected ciphers.
158 {
159 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700160 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500161 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
162 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700163 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500164 // Select ECDHE ones and sort them by strength. Ties should resolve
165 // based on the order above.
166 "kECDHE:@STRENGTH:-ALL:"
167 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
168 // by strength. Then RSA, backwards by strength.
169 "aRSA",
170 {
171 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
172 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500173 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500174 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
175 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
176 },
177 },
178 // Exact ciphers may not be used in multi-part rules; they are treated
179 // as unknown aliases.
180 {
181 "ECDHE-ECDSA-AES128-GCM-SHA256:"
182 "ECDHE-RSA-AES128-GCM-SHA256:"
183 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
184 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
185 {
186 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
187 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
188 },
189 },
190 // SSLv3 matches everything that existed before TLS 1.2.
191 {
192 "AES128-SHA:AES128-SHA256:!SSLv3",
193 {
194 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
195 },
196 },
197 // TLSv1.2 matches everything added in TLS 1.2.
198 {
199 "AES128-SHA:AES128-SHA256:!TLSv1.2",
200 {
201 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
202 },
203 },
204 // The two directives have no intersection.
205 {
206 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
207 {
208 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
209 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
210 },
211 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400212};
213
214static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400215 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400216 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
217 "RSA]",
218 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400219 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400220 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400221 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400222 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400223 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400224 "",
225 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400226 // COMPLEMENTOFDEFAULT is empty.
227 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400228 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400229 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400230 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400231 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
232 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
233 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
234 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700235 // Opcode supplied, but missing selector.
236 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400237};
238
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700239static const char *kMustNotIncludeNull[] = {
240 "ALL",
241 "DEFAULT",
242 "ALL:!eNULL",
243 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500244 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700245 "FIPS",
246 "SHA",
247 "SHA1",
248 "RSA",
249 "SSLv3",
250 "TLSv1",
251 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700252};
253
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100254static const CurveTest kCurveTests[] = {
255 {
256 "P-256",
257 { SSL_CURVE_SECP256R1 },
258 },
259 {
260 "P-256:P-384:P-521:X25519",
261 {
262 SSL_CURVE_SECP256R1,
263 SSL_CURVE_SECP384R1,
264 SSL_CURVE_SECP521R1,
265 SSL_CURVE_X25519,
266 },
267 },
268};
269
270static const char *kBadCurvesLists[] = {
271 "",
272 ":",
273 "::",
274 "P-256::X25519",
275 "RSA:P-256",
276 "P-256:RSA",
277 "X25519:P-256:",
278 ":X25519:P-256",
279};
280
David Benjamin1d77e562015-03-22 17:22:08 -0400281static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
282 bool in_group = false;
283 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400284 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
285 if (!in_group && list->in_group_flags[i]) {
286 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400287 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400288 }
289 fprintf(stderr, "\t");
290 if (in_group) {
291 fprintf(stderr, " ");
292 }
293 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
294 if (in_group && !list->in_group_flags[i]) {
295 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400296 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400297 }
298 }
299}
300
David Benjaminfb974e62015-12-16 19:34:22 -0500301static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700302 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400303 if (!ctx) {
304 return false;
David Benjamin65226252015-02-05 16:49:47 -0500305 }
306
David Benjaminfb974e62015-12-16 19:34:22 -0500307 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
308 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400309 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400310 }
311
David Benjamin1d77e562015-03-22 17:22:08 -0400312 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500313 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
314 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
315 PrintCipherPreferenceList(ctx->cipher_list);
316 return false;
317 }
318
319 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400320 const SSL_CIPHER *cipher =
321 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500322 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
323 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
324 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400325 PrintCipherPreferenceList(ctx->cipher_list);
326 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400327 }
328 }
329
David Benjamin1d77e562015-03-22 17:22:08 -0400330 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400331}
332
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700333static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700334 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700335 if (!ctx) {
336 return false;
337 }
338 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
339 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
340 return false;
341 }
342 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
343 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
344 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
345 return false;
346 }
347 }
348 return true;
349}
350
David Benjamin1d77e562015-03-22 17:22:08 -0400351static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500352 for (const CipherTest &test : kCipherTests) {
353 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400354 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400355 }
356 }
357
David Benjaminfb974e62015-12-16 19:34:22 -0500358 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700359 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400360 if (!ctx) {
361 return false;
David Benjamin65226252015-02-05 16:49:47 -0500362 }
David Benjaminfb974e62015-12-16 19:34:22 -0500363 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
364 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400365 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400366 }
367 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400368 }
369
David Benjaminfb974e62015-12-16 19:34:22 -0500370 for (const char *rule : kMustNotIncludeNull) {
371 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700372 return false;
373 }
374 }
375
David Benjamin1d77e562015-03-22 17:22:08 -0400376 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400377}
David Benjamin2e521212014-07-16 14:37:51 -0400378
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100379static bool TestCurveRule(const CurveTest &t) {
380 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
381 if (!ctx) {
382 return false;
383 }
384
385 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
386 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
387 return false;
388 }
389
390 // Compare the two lists.
391 if (ctx->supported_group_list_len != t.expected.size()) {
392 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
393 return false;
394 }
395
396 for (size_t i = 0; i < t.expected.size(); i++) {
397 if (t.expected[i] != ctx->supported_group_list[i]) {
398 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
399 return false;
400 }
401 }
402
403 return true;
404}
405
406static bool TestCurveRules() {
407 for (const CurveTest &test : kCurveTests) {
408 if (!TestCurveRule(test)) {
409 return false;
410 }
411 }
412
413 for (const char *rule : kBadCurvesLists) {
414 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
415 if (!ctx) {
416 return false;
417 }
418 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
419 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
420 return false;
421 }
422 ERR_clear_error();
423 }
424
425 return true;
426}
427
Adam Langley364f7a62016-12-12 10:51:00 -0800428// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700429static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800430 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700431 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
432 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
433 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
434 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
435 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
436 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
437 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
438 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
439 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
440 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
441 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
442 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
443 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
444 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
445 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
446 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
447 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
448 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
449 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
450 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
451 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
452 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
453 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
454 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
455 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
456 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
457 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
458 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
459 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800460 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700461
462// kCustomSession is a custom serialized SSL_SESSION generated by
463// filling in missing fields from |kOpenSSLSession|. This includes
464// providing |peer_sha256|, so |peer| is not serialized.
465static const char kCustomSession[] =
466 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
467 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
468 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
469 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
470 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
471 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
472 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
473 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
474
475// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
476static const char kBoringSSLSession[] =
477 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
478 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
479 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
480 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
481 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
482 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
483 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
484 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
485 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
486 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
487 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
488 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
489 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
490 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
491 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
492 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
493 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
494 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
495 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
496 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
497 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
498 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
499 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
500 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
501 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
502 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
503 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
504 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
505 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
506 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
507 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
508 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
509 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
510 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
511 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
512 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
513 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
514 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
515 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
516 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
517 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
518 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
519 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
520 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
521 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
522 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
523 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
524 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
525 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
526 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
527 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
528 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
529 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
530 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
531 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
532 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
533 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
534 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
535 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
536 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
537 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
538 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
539 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
540 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
541 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
542 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
543 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
544 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
545 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
546 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
547 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
548 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
549 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
550 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
551 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
552 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
553 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
554 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
555 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
556 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
557 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
558 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
559 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
560 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
561 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
562 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
563 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
564 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
565 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
566 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
567 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
568 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
569 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
570 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
571 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
572
573// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
574// the final (optional) element of |kCustomSession| with tag number 30.
575static const char kBadSessionExtraField[] =
576 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
577 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
578 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
579 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
580 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
581 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
582 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
583 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
584
585// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
586// the version of |kCustomSession| with 2.
587static const char kBadSessionVersion[] =
588 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
589 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
590 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
591 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
592 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
593 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
594 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
595 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
596
597// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
598// appended.
599static const char kBadSessionTrailingData[] =
600 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
601 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
602 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
603 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
604 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
605 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
606 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
607 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
608
David Benjamin1d77e562015-03-22 17:22:08 -0400609static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400610 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400611 if (!EVP_DecodedLength(&len, strlen(in))) {
612 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400613 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400614 }
615
David Benjamin1d77e562015-03-22 17:22:08 -0400616 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800617 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400618 strlen(in))) {
619 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400620 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400621 }
David Benjamin1d77e562015-03-22 17:22:08 -0400622 out->resize(len);
623 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400624}
625
David Benjamin1d77e562015-03-22 17:22:08 -0400626static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400627 const uint8_t *cptr;
628 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400629
David Benjamin1d77e562015-03-22 17:22:08 -0400630 // Decode the input.
631 std::vector<uint8_t> input;
632 if (!DecodeBase64(&input, input_b64)) {
633 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400634 }
635
David Benjamin1d77e562015-03-22 17:22:08 -0400636 // Verify the SSL_SESSION decodes.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800637 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400638 if (!session) {
639 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400640 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400641 }
642
David Benjamin1d77e562015-03-22 17:22:08 -0400643 // Verify the SSL_SESSION encoding round-trips.
644 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700645 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400646 uint8_t *encoded_raw;
647 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400648 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400649 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400650 }
David Benjamin1d77e562015-03-22 17:22:08 -0400651 encoded.reset(encoded_raw);
652 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500653 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400654 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200655 hexdump(stderr, "Before: ", input.data(), input.size());
656 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400657 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400658 }
David Benjamin3cac4502014-10-21 01:46:30 -0400659
David Benjaminfd67aa82015-06-15 19:41:48 -0400660 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800661 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400662 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800663 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400664 fprintf(stderr, "d2i_SSL_SESSION failed\n");
665 return false;
666 }
667
David Benjamin1d77e562015-03-22 17:22:08 -0400668 // Verify the SSL_SESSION encoding round-trips via the legacy API.
669 int len = i2d_SSL_SESSION(session.get(), NULL);
670 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400671 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400672 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400673 }
674
David Benjamin1d77e562015-03-22 17:22:08 -0400675 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
676 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400677 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400678 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400679 }
David Benjamin1d77e562015-03-22 17:22:08 -0400680
681 ptr = encoded.get();
682 len = i2d_SSL_SESSION(session.get(), &ptr);
683 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400684 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400685 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400686 }
David Benjamin1d77e562015-03-22 17:22:08 -0400687 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400688 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400689 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400690 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500691 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400692 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400693 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400694 }
695
David Benjamin1d77e562015-03-22 17:22:08 -0400696 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400697}
698
David Benjaminf297e022015-05-28 19:55:29 -0400699static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
700 std::vector<uint8_t> input;
701 if (!DecodeBase64(&input, input_b64)) {
702 return false;
703 }
704
705 // Verify that the SSL_SESSION fails to decode.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800706 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400707 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400708 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400709 return false;
710 }
711 ERR_clear_error();
712 return true;
713}
714
David Benjamin10e664b2016-06-20 22:20:47 -0400715static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400716 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700717 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400718 if (!ctx) {
719 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500720 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400721 if (ctx->min_version != min_version || ctx->max_version != max_version) {
722 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
723 ctx->min_version, ctx->max_version, min_version, max_version);
724 return false;
725 }
726 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500727}
728
David Benjamin1d77e562015-03-22 17:22:08 -0400729static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500730 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
731 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400732 return false;
David Benjamin65226252015-02-05 16:49:47 -0500733 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700734 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400735 if (!rfc_name) {
736 return false;
737 }
David Benjamin67be0482015-04-20 16:19:00 -0400738 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400739 return true;
David Benjamin65226252015-02-05 16:49:47 -0500740}
741
742typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500743 int id;
David Benjamin65226252015-02-05 16:49:47 -0500744 const char *rfc_name;
745} CIPHER_RFC_NAME_TEST;
746
747static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400748 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
749 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
750 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
751 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
752 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
753 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
754 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
755 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
756 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
757 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
758 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
759 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
760 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
761 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
762 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
763 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
764 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
765 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
766 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
767 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
768 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
769 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500770};
771
David Benjamin1d77e562015-03-22 17:22:08 -0400772static bool TestCipherGetRFCName(void) {
773 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400774 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500775 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400776 std::string rfc_name;
777 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
778 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
779 return false;
David Benjamin65226252015-02-05 16:49:47 -0500780 }
David Benjamin1d77e562015-03-22 17:22:08 -0400781 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500782 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400783 rfc_name.c_str(), test->rfc_name);
784 return false;
David Benjamin65226252015-02-05 16:49:47 -0500785 }
David Benjamin65226252015-02-05 16:49:47 -0500786 }
David Benjamin1d77e562015-03-22 17:22:08 -0400787 return true;
David Benjamin65226252015-02-05 16:49:47 -0500788}
789
Steven Valdeza833c352016-11-01 13:39:36 -0400790// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
791// version and ticket length or nullptr on failure.
792static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
793 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400794 std::vector<uint8_t> der;
795 if (!DecodeBase64(&der, kOpenSSLSession)) {
796 return nullptr;
797 }
Steven Valdeza833c352016-11-01 13:39:36 -0400798 bssl::UniquePtr<SSL_SESSION> session(
799 SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400800 if (!session) {
801 return nullptr;
802 }
803
Steven Valdeza833c352016-11-01 13:39:36 -0400804 session->ssl_version = version;
805
David Benjamin422fe082015-07-21 22:03:43 -0400806 // Swap out the ticket for a garbage one.
807 OPENSSL_free(session->tlsext_tick);
808 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
809 if (session->tlsext_tick == nullptr) {
810 return nullptr;
811 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500812 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400813 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400814
815 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500816#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
817 session->time = 1234;
818#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400819 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500820#endif
David Benjamin422fe082015-07-21 22:03:43 -0400821 return session;
822}
823
David Benjaminafc64de2016-07-19 17:12:41 +0200824static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700825 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200826 if (!bio) {
827 return false;
828 }
829 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400830 BIO_up_ref(bio.get());
831 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200832 int ret = SSL_connect(ssl);
833 if (ret > 0) {
834 // SSL_connect should fail without a BIO to write to.
835 return false;
836 }
837 ERR_clear_error();
838
839 const uint8_t *client_hello;
840 size_t client_hello_len;
841 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
842 return false;
843 }
844 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
845 return true;
846}
847
Steven Valdeza833c352016-11-01 13:39:36 -0400848// GetClientHelloLen creates a client SSL connection with the specified version
849// and ticket length. It returns the length of the ClientHello, not including
850// the record header, on success and zero on error.
851static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
852 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700853 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400854 bssl::UniquePtr<SSL_SESSION> session =
855 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400856 if (!ctx || !session) {
857 return 0;
858 }
Steven Valdeza833c352016-11-01 13:39:36 -0400859
860 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700861 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400862 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400863 !SSL_set_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
864 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400865 return 0;
866 }
Steven Valdeza833c352016-11-01 13:39:36 -0400867
David Benjaminafc64de2016-07-19 17:12:41 +0200868 std::vector<uint8_t> client_hello;
869 if (!GetClientHello(ssl.get(), &client_hello) ||
870 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400871 return 0;
872 }
Steven Valdeza833c352016-11-01 13:39:36 -0400873
David Benjaminafc64de2016-07-19 17:12:41 +0200874 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400875}
876
877struct PaddingTest {
878 size_t input_len, padded_len;
879};
880
881static const PaddingTest kPaddingTests[] = {
882 // ClientHellos of length below 0x100 do not require padding.
883 {0xfe, 0xfe},
884 {0xff, 0xff},
885 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
886 {0x100, 0x200},
887 {0x123, 0x200},
888 {0x1fb, 0x200},
889 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
890 // padding extension takes a minimum of four bytes plus one required content
891 // byte. (To work around yet more server bugs, we avoid empty final
892 // extensions.)
893 {0x1fc, 0x201},
894 {0x1fd, 0x202},
895 {0x1fe, 0x203},
896 {0x1ff, 0x204},
897 // Finally, larger ClientHellos need no padding.
898 {0x200, 0x200},
899 {0x201, 0x201},
900};
901
Steven Valdeza833c352016-11-01 13:39:36 -0400902static bool TestPaddingExtension(uint16_t max_version,
903 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400904 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400905 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400906 if (base_len == 0) {
907 return false;
908 }
909
910 for (const PaddingTest &test : kPaddingTests) {
911 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400912 fprintf(stderr,
913 "Baseline ClientHello too long (max_version = %04x, "
914 "session_version = %04x).\n",
915 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400916 return false;
917 }
918
Steven Valdeza833c352016-11-01 13:39:36 -0400919 size_t padded_len = GetClientHelloLen(max_version, session_version,
920 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400921 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400922 fprintf(stderr,
923 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
924 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400925 static_cast<unsigned>(test.input_len),
926 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400927 static_cast<unsigned>(test.padded_len), max_version,
928 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400929 return false;
930 }
931 }
Steven Valdeza833c352016-11-01 13:39:36 -0400932
David Benjamin422fe082015-07-21 22:03:43 -0400933 return true;
934}
935
David Benjamin1d128f32015-09-08 17:41:40 -0400936// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
937// before configuring as a server.
938static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700939 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400940 if (!ctx) {
941 return false;
942 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700943 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400944 if (!ssl) {
945 return false;
946 }
947
948 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
949 if (stack == nullptr) {
950 return false;
951 }
952 // |SSL_set_client_CA_list| takes ownership.
953 SSL_set_client_CA_list(ssl.get(), stack);
954
955 return SSL_get_client_CA_list(ssl.get()) == stack;
956}
957
David Benjamin0f653952015-10-18 14:28:01 -0400958static void AppendSession(SSL_SESSION *session, void *arg) {
959 std::vector<SSL_SESSION*> *out =
960 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
961 out->push_back(session);
962}
963
964// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
965// order.
966static bool ExpectCache(SSL_CTX *ctx,
967 const std::vector<SSL_SESSION*> &expected) {
968 // Check the linked list.
969 SSL_SESSION *ptr = ctx->session_cache_head;
970 for (SSL_SESSION *session : expected) {
971 if (ptr != session) {
972 return false;
973 }
974 // TODO(davidben): This is an absurd way to denote the end of the list.
975 if (ptr->next ==
976 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
977 ptr = nullptr;
978 } else {
979 ptr = ptr->next;
980 }
981 }
982 if (ptr != nullptr) {
983 return false;
984 }
985
986 // Check the hash table.
987 std::vector<SSL_SESSION*> actual, expected_copy;
988 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
989 expected_copy = expected;
990
991 std::sort(actual.begin(), actual.end());
992 std::sort(expected_copy.begin(), expected_copy.end());
993
994 return actual == expected_copy;
995}
996
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700997static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
998 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -0400999 if (!ret) {
1000 return nullptr;
1001 }
1002
1003 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001004 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1005 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001006 return ret;
1007}
1008
David Benjamin0f653952015-10-18 14:28:01 -04001009// Test that the internal session cache behaves as expected.
1010static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001011 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001012 if (!ctx) {
1013 return false;
1014 }
1015
1016 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001017 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001018 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001019 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001020 if (!session) {
1021 return false;
1022 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001023 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001024 }
1025
1026 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1027
1028 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001029 for (const auto &session : sessions) {
1030 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001031 return false;
1032 }
1033 }
1034
1035 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001036 std::vector<SSL_SESSION*> expected = {
1037 sessions[9].get(),
1038 sessions[8].get(),
1039 sessions[7].get(),
1040 sessions[6].get(),
1041 sessions[5].get(),
1042 };
David Benjamin0f653952015-10-18 14:28:01 -04001043 if (!ExpectCache(ctx.get(), expected)) {
1044 return false;
1045 }
1046
1047 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001048 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001049 !ExpectCache(ctx.get(), expected)) {
1050 return false;
1051 }
1052
1053 // Although collisions should be impossible (256-bit session IDs), the cache
1054 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001055 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001056 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1057 return false;
1058 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001059 expected = {
1060 collision.get(),
1061 sessions[9].get(),
1062 sessions[8].get(),
1063 sessions[6].get(),
1064 sessions[5].get(),
1065 };
David Benjamin0f653952015-10-18 14:28:01 -04001066 if (!ExpectCache(ctx.get(), expected)) {
1067 return false;
1068 }
1069
1070 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001071 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001072 return false;
1073 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001074 expected = {
1075 collision.get(),
1076 sessions[9].get(),
1077 sessions[8].get(),
1078 sessions[5].get(),
1079 };
David Benjamin0f653952015-10-18 14:28:01 -04001080 if (!ExpectCache(ctx.get(), expected)) {
1081 return false;
1082 }
1083
1084 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001085 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1086 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001087 !ExpectCache(ctx.get(), expected)) {
1088 return false;
1089 }
1090
1091 return true;
1092}
1093
David Benjaminde942382016-02-11 12:02:01 -05001094static uint16_t EpochFromSequence(uint64_t seq) {
1095 return static_cast<uint16_t>(seq >> 48);
1096}
1097
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001098static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001099 static const char kCertPEM[] =
1100 "-----BEGIN CERTIFICATE-----\n"
1101 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1102 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1103 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1104 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1105 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1106 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1107 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1108 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1109 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1110 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1111 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1112 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1113 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1114 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001115 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001116 return bssl::UniquePtr<X509>(
1117 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001118}
1119
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001120static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001121 static const char kKeyPEM[] =
1122 "-----BEGIN RSA PRIVATE KEY-----\n"
1123 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1124 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1125 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1126 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1127 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1128 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1129 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1130 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1131 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1132 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1133 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1134 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1135 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1136 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001137 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1138 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001139 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1140}
1141
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001142static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001143 static const char kCertPEM[] =
1144 "-----BEGIN CERTIFICATE-----\n"
1145 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1146 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1147 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1148 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1149 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1150 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1151 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1152 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1153 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1154 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1155 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001156 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1157 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001158}
1159
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001160static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001161 static const char kKeyPEM[] =
1162 "-----BEGIN PRIVATE KEY-----\n"
1163 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1164 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1165 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1166 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1168 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001169 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1170}
1171
David Benjamin1444c3a2016-12-20 17:23:11 -05001172static bssl::UniquePtr<X509> GetChainTestCertificate() {
1173 static const char kCertPEM[] =
1174 "-----BEGIN CERTIFICATE-----\n"
1175 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1176 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1177 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1178 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1179 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1180 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1181 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1182 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1183 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1184 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1185 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1186 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1187 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1188 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1189 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1190 "1ngWZ7Ih\n"
1191 "-----END CERTIFICATE-----\n";
1192 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1193 return bssl::UniquePtr<X509>(
1194 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1195}
1196
1197static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1198 static const char kCertPEM[] =
1199 "-----BEGIN CERTIFICATE-----\n"
1200 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1201 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1202 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1203 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1204 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1205 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1206 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1207 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1208 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1209 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1210 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1211 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1212 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1213 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1214 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1215 "-----END CERTIFICATE-----\n";
1216 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1217 return bssl::UniquePtr<X509>(
1218 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1219}
1220
1221static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1222 static const char kKeyPEM[] =
1223 "-----BEGIN PRIVATE KEY-----\n"
1224 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1225 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1226 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1227 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1228 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1229 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1230 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1231 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1232 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1233 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1234 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1235 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1236 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1237 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1238 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1239 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1240 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1241 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1242 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1243 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1244 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1245 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1246 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1247 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1248 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1249 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1250 "-----END PRIVATE KEY-----\n";
1251 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1252 return bssl::UniquePtr<EVP_PKEY>(
1253 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1254}
1255
David Benjaminb79cc842016-12-07 15:57:14 -05001256static bool CompleteHandshakes(SSL *client, SSL *server) {
1257 // Drive both their handshakes to completion.
1258 for (;;) {
1259 int client_ret = SSL_do_handshake(client);
1260 int client_err = SSL_get_error(client, client_ret);
1261 if (client_err != SSL_ERROR_NONE &&
1262 client_err != SSL_ERROR_WANT_READ &&
1263 client_err != SSL_ERROR_WANT_WRITE) {
1264 fprintf(stderr, "Client error: %d\n", client_err);
1265 return false;
1266 }
1267
1268 int server_ret = SSL_do_handshake(server);
1269 int server_err = SSL_get_error(server, server_ret);
1270 if (server_err != SSL_ERROR_NONE &&
1271 server_err != SSL_ERROR_WANT_READ &&
1272 server_err != SSL_ERROR_WANT_WRITE) {
1273 fprintf(stderr, "Server error: %d\n", server_err);
1274 return false;
1275 }
1276
1277 if (client_ret == 1 && server_ret == 1) {
1278 break;
1279 }
1280 }
1281
1282 return true;
1283}
1284
1285static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1286 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001287 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1288 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001289 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001290 if (!client || !server) {
1291 return false;
1292 }
1293 SSL_set_connect_state(client.get());
1294 SSL_set_accept_state(server.get());
1295
David Benjamina20e5352016-08-02 19:09:41 -04001296 SSL_set_session(client.get(), session);
1297
David Benjaminde942382016-02-11 12:02:01 -05001298 BIO *bio1, *bio2;
1299 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1300 return false;
1301 }
1302 // SSL_set_bio takes ownership.
1303 SSL_set_bio(client.get(), bio1, bio1);
1304 SSL_set_bio(server.get(), bio2, bio2);
1305
David Benjaminb79cc842016-12-07 15:57:14 -05001306 if (!CompleteHandshakes(client.get(), server.get())) {
1307 return false;
David Benjaminde942382016-02-11 12:02:01 -05001308 }
1309
David Benjamin686bb192016-05-10 15:15:41 -04001310 *out_client = std::move(client);
1311 *out_server = std::move(server);
1312 return true;
1313}
1314
David Benjamin0fef3052016-11-18 15:11:10 +09001315static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1316 uint16_t version) {
1317 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1318 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1319 if (!server_ctx || !client_ctx ||
1320 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1321 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1322 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1323 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1324 return false;
1325 }
David Benjamin686bb192016-05-10 15:15:41 -04001326
David Benjamin0fef3052016-11-18 15:11:10 +09001327 bssl::UniquePtr<X509> cert = GetTestCertificate();
1328 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1329 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1330 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1331 return false;
1332 }
David Benjamin686bb192016-05-10 15:15:41 -04001333
David Benjamin0fef3052016-11-18 15:11:10 +09001334 bssl::UniquePtr<SSL> client, server;
1335 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1336 server_ctx.get(), nullptr /* no session */)) {
1337 return false;
1338 }
David Benjamin686bb192016-05-10 15:15:41 -04001339
David Benjamin0fef3052016-11-18 15:11:10 +09001340 // Drain any post-handshake messages to ensure there are no unread records
1341 // on either end.
1342 uint8_t byte = 0;
1343 if (SSL_read(client.get(), &byte, 1) > 0 ||
1344 SSL_read(server.get(), &byte, 1) > 0) {
1345 fprintf(stderr, "Received unexpected data.\n");
1346 return false;
1347 }
David Benjaminde942382016-02-11 12:02:01 -05001348
David Benjamin0fef3052016-11-18 15:11:10 +09001349 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1350 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1351 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1352 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001353
David Benjamin0fef3052016-11-18 15:11:10 +09001354 if (is_dtls) {
1355 // Both client and server must be at epoch 1.
1356 if (EpochFromSequence(client_read_seq) != 1 ||
1357 EpochFromSequence(client_write_seq) != 1 ||
1358 EpochFromSequence(server_read_seq) != 1 ||
1359 EpochFromSequence(server_write_seq) != 1) {
1360 fprintf(stderr, "Bad epochs.\n");
1361 return false;
David Benjaminde942382016-02-11 12:02:01 -05001362 }
David Benjamin0fef3052016-11-18 15:11:10 +09001363
1364 // The next record to be written should exceed the largest 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 } else {
1371 // The next record to be written should equal the next to be received.
1372 if (client_write_seq != server_read_seq ||
1373 server_write_seq != client_read_seq) {
1374 fprintf(stderr, "Inconsistent sequence numbers.\n");
1375 return false;
1376 }
1377 }
1378
1379 // Send a record from client to server.
1380 if (SSL_write(client.get(), &byte, 1) != 1 ||
1381 SSL_read(server.get(), &byte, 1) != 1) {
1382 fprintf(stderr, "Could not send byte.\n");
1383 return false;
1384 }
1385
1386 // The client write and server read sequence numbers should have
1387 // incremented.
1388 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1389 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1390 fprintf(stderr, "Sequence numbers did not increment.\n");
1391 return false;
David Benjaminde942382016-02-11 12:02:01 -05001392 }
1393
1394 return true;
1395}
1396
David Benjamin68f37b72016-11-18 15:14:42 +09001397static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1398 uint16_t version) {
1399 // SSL_shutdown is a no-op in DTLS.
1400 if (is_dtls) {
1401 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001402 }
1403
David Benjamin68f37b72016-11-18 15:14:42 +09001404 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1405 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001406 bssl::UniquePtr<X509> cert = GetTestCertificate();
1407 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001408 if (!client_ctx || !server_ctx || !cert || !key ||
1409 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1410 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1411 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1412 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001413 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1414 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1415 return false;
1416 }
1417
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001418 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001419 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001420 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001421 return false;
1422 }
1423
1424 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1425 // one side has shut down.
1426 if (SSL_shutdown(client.get()) != 0) {
1427 fprintf(stderr, "Could not shutdown.\n");
1428 return false;
1429 }
1430
1431 // Reading from the server should consume the EOF.
1432 uint8_t byte;
1433 if (SSL_read(server.get(), &byte, 1) != 0 ||
1434 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1435 fprintf(stderr, "Connection was not shut down cleanly.\n");
1436 return false;
1437 }
1438
1439 // However, the server may continue to write data and then shut down the
1440 // connection.
1441 byte = 42;
1442 if (SSL_write(server.get(), &byte, 1) != 1 ||
1443 SSL_read(client.get(), &byte, 1) != 1 ||
1444 byte != 42) {
1445 fprintf(stderr, "Could not send byte.\n");
1446 return false;
1447 }
1448
1449 // The server may then shutdown the connection.
1450 if (SSL_shutdown(server.get()) != 1 ||
1451 SSL_shutdown(client.get()) != 1) {
1452 fprintf(stderr, "Could not complete shutdown.\n");
1453 return false;
1454 }
1455
1456 return true;
1457}
David Benjamin68f37b72016-11-18 15:14:42 +09001458
Steven Valdez87eab492016-06-27 16:34:59 -04001459static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001460 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1461 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001462 if (!client_ctx || !server_ctx) {
1463 return false;
1464 }
1465
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001466 bssl::UniquePtr<X509> cert = GetTestCertificate();
1467 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001468 if (!cert || !key ||
1469 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1470 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1471 return false;
1472 }
1473
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001474 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001475 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001476 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001477 return false;
1478 }
1479
1480 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001481 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001482 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001483 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001484 }
David Benjamin4501bd52016-08-01 13:39:41 -04001485
Steven Valdez84b5c002016-08-25 16:30:58 -04001486 session1->not_resumable = 0;
1487
Steven Valdez87eab492016-06-27 16:34:59 -04001488 uint8_t *s0_bytes, *s1_bytes;
1489 size_t s0_len, s1_len;
1490
1491 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1492 return false;
1493 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001494 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001495
1496 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1497 return false;
1498 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001499 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001500
David Benjamin17cf2cb2016-12-13 01:07:13 -05001501 return s0_len == s1_len && OPENSSL_memcmp(s0_bytes, s1_bytes, s0_len) == 0;
Steven Valdez87eab492016-06-27 16:34:59 -04001502}
David Benjamin686bb192016-05-10 15:15:41 -04001503
David Benjamin5c0fb882016-06-14 14:03:51 -04001504static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1505 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1506 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1507 SSL_get_wfd(ssl), rfd, wfd);
1508 return false;
1509 }
1510
1511 // The wrapper BIOs are always equal when fds are equal, even if set
1512 // individually.
1513 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1514 fprintf(stderr, "rbio and wbio did not match.\n");
1515 return false;
1516 }
1517
1518 return true;
1519}
1520
1521static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001522 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001523 if (!ctx) {
1524 return false;
1525 }
1526
1527 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001528 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001529 if (!ssl ||
1530 !SSL_set_rfd(ssl.get(), 1) ||
1531 !SSL_set_wfd(ssl.get(), 2) ||
1532 !ExpectFDs(ssl.get(), 1, 2)) {
1533 return false;
1534 }
1535
1536 // Test setting the same FD.
1537 ssl.reset(SSL_new(ctx.get()));
1538 if (!ssl ||
1539 !SSL_set_fd(ssl.get(), 1) ||
1540 !ExpectFDs(ssl.get(), 1, 1)) {
1541 return false;
1542 }
1543
1544 // Test setting the same FD one side at a time.
1545 ssl.reset(SSL_new(ctx.get()));
1546 if (!ssl ||
1547 !SSL_set_rfd(ssl.get(), 1) ||
1548 !SSL_set_wfd(ssl.get(), 1) ||
1549 !ExpectFDs(ssl.get(), 1, 1)) {
1550 return false;
1551 }
1552
1553 // Test setting the same FD in the other order.
1554 ssl.reset(SSL_new(ctx.get()));
1555 if (!ssl ||
1556 !SSL_set_wfd(ssl.get(), 1) ||
1557 !SSL_set_rfd(ssl.get(), 1) ||
1558 !ExpectFDs(ssl.get(), 1, 1)) {
1559 return false;
1560 }
1561
David Benjamin5c0fb882016-06-14 14:03:51 -04001562 // Test changing the read FD partway through.
1563 ssl.reset(SSL_new(ctx.get()));
1564 if (!ssl ||
1565 !SSL_set_fd(ssl.get(), 1) ||
1566 !SSL_set_rfd(ssl.get(), 2) ||
1567 !ExpectFDs(ssl.get(), 2, 1)) {
1568 return false;
1569 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001570
1571 // Test changing the write FD partway through.
1572 ssl.reset(SSL_new(ctx.get()));
1573 if (!ssl ||
1574 !SSL_set_fd(ssl.get(), 1) ||
1575 !SSL_set_wfd(ssl.get(), 2) ||
1576 !ExpectFDs(ssl.get(), 1, 2)) {
1577 return false;
1578 }
1579
1580 // Test a no-op change to the read FD partway through.
1581 ssl.reset(SSL_new(ctx.get()));
1582 if (!ssl ||
1583 !SSL_set_fd(ssl.get(), 1) ||
1584 !SSL_set_rfd(ssl.get(), 1) ||
1585 !ExpectFDs(ssl.get(), 1, 1)) {
1586 return false;
1587 }
1588
1589 // Test a no-op change to the write FD partway through.
1590 ssl.reset(SSL_new(ctx.get()));
1591 if (!ssl ||
1592 !SSL_set_fd(ssl.get(), 1) ||
1593 !SSL_set_wfd(ssl.get(), 1) ||
1594 !ExpectFDs(ssl.get(), 1, 1)) {
1595 return false;
1596 }
1597
1598 // ASan builds will implicitly test that the internal |BIO| reference-counting
1599 // is correct.
1600
1601 return true;
1602}
1603
David Benjamin4501bd52016-08-01 13:39:41 -04001604static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001605 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001606 if (!ctx) {
1607 return false;
1608 }
1609
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001610 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1611 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001612 bio3(BIO_new(BIO_s_mem()));
1613 if (!ssl || !bio1 || !bio2 || !bio3) {
1614 return false;
1615 }
1616
1617 // SSL_set_bio takes one reference when the parameters are the same.
1618 BIO_up_ref(bio1.get());
1619 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1620
1621 // Repeating the call does nothing.
1622 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1623
1624 // It takes one reference each when the parameters are different.
1625 BIO_up_ref(bio2.get());
1626 BIO_up_ref(bio3.get());
1627 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1628
1629 // Repeating the call does nothing.
1630 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1631
1632 // It takes one reference when changing only wbio.
1633 BIO_up_ref(bio1.get());
1634 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1635
1636 // It takes one reference when changing only rbio and the two are different.
1637 BIO_up_ref(bio3.get());
1638 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1639
1640 // If setting wbio to rbio, it takes no additional references.
1641 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1642
1643 // From there, wbio may be switched to something else.
1644 BIO_up_ref(bio1.get());
1645 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1646
1647 // If setting rbio to wbio, it takes no additional references.
1648 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1649
1650 // From there, rbio may be switched to something else, but, for historical
1651 // reasons, it takes a reference to both parameters.
1652 BIO_up_ref(bio1.get());
1653 BIO_up_ref(bio2.get());
1654 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1655
1656 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1657 // is correct.
1658 return true;
1659}
1660
David Benjamin25490f22016-07-14 00:22:54 -04001661static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1662
David Benjamin0fef3052016-11-18 15:11:10 +09001663static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1664 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001665 bssl::UniquePtr<X509> cert = GetTestCertificate();
1666 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001667 if (!cert || !key) {
1668 return false;
1669 }
1670
David Benjamin0fef3052016-11-18 15:11:10 +09001671 // Configure both client and server to accept any certificate.
1672 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1673 if (!ctx ||
1674 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1675 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1676 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1677 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1678 return false;
1679 }
1680 SSL_CTX_set_verify(
1681 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1682 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001683
David Benjamin0fef3052016-11-18 15:11:10 +09001684 bssl::UniquePtr<SSL> client, server;
1685 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1686 nullptr /* no session */)) {
1687 return false;
1688 }
David Benjaminadd5e522016-07-14 00:33:24 -04001689
David Benjamin0fef3052016-11-18 15:11:10 +09001690 // Client and server should both see the leaf certificate.
1691 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1692 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1693 fprintf(stderr, "Server peer certificate did not match.\n");
1694 return false;
1695 }
David Benjaminadd5e522016-07-14 00:33:24 -04001696
David Benjamin0fef3052016-11-18 15:11:10 +09001697 peer.reset(SSL_get_peer_certificate(client.get()));
1698 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1699 fprintf(stderr, "Client peer certificate did not match.\n");
1700 return false;
1701 }
David Benjaminadd5e522016-07-14 00:33:24 -04001702
David Benjamin0fef3052016-11-18 15:11:10 +09001703 // However, for historical reasons, the chain includes the leaf on the
1704 // client, but does not on the server.
1705 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1706 fprintf(stderr, "Client peer chain was incorrect.\n");
1707 return false;
1708 }
David Benjaminadd5e522016-07-14 00:33:24 -04001709
David Benjamin0fef3052016-11-18 15:11:10 +09001710 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1711 fprintf(stderr, "Server peer chain was incorrect.\n");
1712 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001713 }
1714
1715 return true;
1716}
1717
David Benjamin0fef3052016-11-18 15:11:10 +09001718static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1719 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001720 bssl::UniquePtr<X509> cert = GetTestCertificate();
1721 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001722 if (!cert || !key) {
1723 return false;
1724 }
1725
1726 uint8_t *cert_der = NULL;
1727 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1728 if (cert_der_len < 0) {
1729 return false;
1730 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001731 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001732
1733 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1734 SHA256(cert_der, cert_der_len, cert_sha256);
1735
David Benjamin0fef3052016-11-18 15:11:10 +09001736 // Configure both client and server to accept any certificate, but the
1737 // server must retain only the SHA-256 of the peer.
1738 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1739 if (!ctx ||
1740 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1741 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1742 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1743 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1744 return false;
1745 }
1746 SSL_CTX_set_verify(
1747 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1748 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1749 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001750
David Benjamin0fef3052016-11-18 15:11:10 +09001751 bssl::UniquePtr<SSL> client, server;
1752 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1753 nullptr /* no session */)) {
1754 return false;
1755 }
David Benjamin25490f22016-07-14 00:22:54 -04001756
David Benjamin0fef3052016-11-18 15:11:10 +09001757 // The peer certificate has been dropped.
1758 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1759 if (peer) {
1760 fprintf(stderr, "Peer certificate was retained.\n");
1761 return false;
1762 }
David Benjamin25490f22016-07-14 00:22:54 -04001763
David Benjamin0fef3052016-11-18 15:11:10 +09001764 SSL_SESSION *session = SSL_get_session(server.get());
1765 if (!session->peer_sha256_valid) {
1766 fprintf(stderr, "peer_sha256_valid was not set.\n");
1767 return false;
1768 }
David Benjamin25490f22016-07-14 00:22:54 -04001769
David Benjamin17cf2cb2016-12-13 01:07:13 -05001770 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1771 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001772 fprintf(stderr, "peer_sha256 did not match.\n");
1773 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001774 }
1775
1776 return true;
1777}
1778
David Benjaminafc64de2016-07-19 17:12:41 +02001779static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1780 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001781 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001782 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001783 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001784 // Our default cipher list varies by CPU capabilities, so manually place
1785 // the ChaCha20 ciphers in front.
1786 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001787 return false;
1788 }
David Benjamin2dc02042016-09-19 19:57:37 -04001789
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001790 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001791 if (!ssl) {
1792 return false;
1793 }
1794 std::vector<uint8_t> client_hello;
1795 if (!GetClientHello(ssl.get(), &client_hello)) {
1796 return false;
1797 }
1798
1799 // Zero the client_random.
1800 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1801 1 + 3 + // handshake message header
1802 2; // client_version
1803 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1804 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1805 return false;
1806 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001807 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001808
1809 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001810 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001811 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1812 fprintf(stderr, "Got:\n\t");
1813 for (size_t i = 0; i < client_hello.size(); i++) {
1814 fprintf(stderr, "0x%02x, ", client_hello[i]);
1815 }
1816 fprintf(stderr, "\nWanted:\n\t");
1817 for (size_t i = 0; i < expected_len; i++) {
1818 fprintf(stderr, "0x%02x, ", expected[i]);
1819 }
1820 fprintf(stderr, "\n");
1821 return false;
1822 }
1823
1824 return true;
1825}
1826
1827// Tests that our ClientHellos do not change unexpectedly.
1828static bool TestClientHello() {
1829 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001830 0x16,
1831 0x03, 0x00,
1832 0x00, 0x3f,
1833 0x01,
1834 0x00, 0x00, 0x3b,
1835 0x03, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00,
1841 0x00, 0x14,
1842 0xc0, 0x09,
1843 0xc0, 0x13,
1844 0x00, 0x33,
1845 0xc0, 0x0a,
1846 0xc0, 0x14,
1847 0x00, 0x39,
1848 0x00, 0x2f,
1849 0x00, 0x35,
1850 0x00, 0x0a,
1851 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001852 };
1853 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1854 sizeof(kSSL3ClientHello))) {
1855 return false;
1856 }
1857
1858 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001859 0x16,
1860 0x03, 0x01,
1861 0x00, 0x5e,
1862 0x01,
1863 0x00, 0x00, 0x5a,
1864 0x03, 0x01,
1865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00,
1870 0x00, 0x12,
1871 0xc0, 0x09,
1872 0xc0, 0x13,
1873 0x00, 0x33,
1874 0xc0, 0x0a,
1875 0xc0, 0x14,
1876 0x00, 0x39,
1877 0x00, 0x2f,
1878 0x00, 0x35,
1879 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001880 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1881 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1882 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1883 };
1884 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1885 sizeof(kTLS1ClientHello))) {
1886 return false;
1887 }
1888
1889 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001890 0x16,
1891 0x03, 0x01,
1892 0x00, 0x5e,
1893 0x01,
1894 0x00, 0x00, 0x5a,
1895 0x03, 0x02,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1899 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900 0x00,
1901 0x00, 0x12,
1902 0xc0, 0x09,
1903 0xc0, 0x13,
1904 0x00, 0x33,
1905 0xc0, 0x0a,
1906 0xc0, 0x14,
1907 0x00, 0x39,
1908 0x00, 0x2f,
1909 0x00, 0x35,
1910 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001911 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1912 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1913 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1914 };
1915 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1916 sizeof(kTLS11ClientHello))) {
1917 return false;
1918 }
1919
1920 static const uint8_t kTLS12ClientHello[] = {
Adam Langley2e839242017-01-19 15:12:44 -08001921 0x16, 0x03, 0x01, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x96, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001922 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1923 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Adam Langley2e839242017-01-19 15:12:44 -08001924 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xcc, 0xa9,
1925 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e, 0xc0, 0x2c, 0xc0, 0x30,
1926 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0x00, 0x33,
1927 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x39,
1928 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
1929 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
1930 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1931 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1932 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1933 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1934 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001935 };
1936 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1937 sizeof(kTLS12ClientHello))) {
1938 return false;
1939 }
1940
1941 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1942 // implementation has settled enough that it won't change.
1943
1944 return true;
1945}
1946
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001947static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001948
1949static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1950 // Save the most recent session.
1951 g_last_session.reset(session);
1952 return 1;
1953}
1954
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001955static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001956 SSL_CTX *server_ctx) {
1957 g_last_session = nullptr;
1958 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1959
1960 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001961 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001962 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1963 nullptr /* no session */)) {
1964 fprintf(stderr, "Failed to connect client and server.\n");
1965 return nullptr;
1966 }
1967
1968 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1969 SSL_read(client.get(), nullptr, 0);
1970
1971 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1972
1973 if (!g_last_session) {
1974 fprintf(stderr, "Client did not receive a session.\n");
1975 return nullptr;
1976 }
1977 return std::move(g_last_session);
1978}
1979
1980static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1981 SSL_SESSION *session,
1982 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001983 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001984 if (!ConnectClientAndServer(&client, &server, client_ctx,
1985 server_ctx, session)) {
1986 fprintf(stderr, "Failed to connect client and server.\n");
1987 return false;
1988 }
1989
1990 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1991 fprintf(stderr, "Client and server were inconsistent.\n");
1992 return false;
1993 }
1994
1995 bool was_reused = !!SSL_session_reused(client.get());
1996 if (was_reused != reused) {
1997 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1998 was_reused ? "" : " not");
1999 return false;
2000 }
2001
2002 return true;
2003}
2004
David Benjamin3c51d9b2016-11-01 17:50:42 -04002005static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2006 SSL_CTX *server_ctx,
2007 SSL_SESSION *session) {
2008 g_last_session = nullptr;
2009 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2010
2011 bssl::UniquePtr<SSL> client, server;
2012 if (!ConnectClientAndServer(&client, &server, client_ctx,
2013 server_ctx, session)) {
2014 fprintf(stderr, "Failed to connect client and server.\n");
2015 return nullptr;
2016 }
2017
2018 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2019 fprintf(stderr, "Client and server were inconsistent.\n");
2020 return nullptr;
2021 }
2022
2023 if (!SSL_session_reused(client.get())) {
2024 fprintf(stderr, "Session was not reused.\n");
2025 return nullptr;
2026 }
2027
2028 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2029 SSL_read(client.get(), nullptr, 0);
2030
2031 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2032
2033 if (!g_last_session) {
2034 fprintf(stderr, "Client did not receive a renewed session.\n");
2035 return nullptr;
2036 }
2037 return std::move(g_last_session);
2038}
2039
David Benjamina933c382016-10-28 00:10:03 -04002040static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2041 static const uint8_t kContext[] = {3};
2042
2043 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2044 return SSL_TLSEXT_ERR_ALERT_FATAL;
2045 }
2046
2047 return SSL_TLSEXT_ERR_OK;
2048}
2049
David Benjamin731058e2016-12-03 23:15:13 -05002050static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04002051 static const uint8_t kContext[] = {3};
2052
David Benjamin731058e2016-12-03 23:15:13 -05002053 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2054 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04002055 return -1;
2056 }
2057
2058 return 1;
2059}
2060
David Benjamin0fef3052016-11-18 15:11:10 +09002061static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2062 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002063 bssl::UniquePtr<X509> cert = GetTestCertificate();
2064 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002065 if (!cert || !key) {
2066 return false;
2067 }
2068
2069 static const uint8_t kContext1[] = {1};
2070 static const uint8_t kContext2[] = {2};
2071
David Benjamin0fef3052016-11-18 15:11:10 +09002072 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2073 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2074 if (!server_ctx || !client_ctx ||
2075 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2076 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2077 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2078 sizeof(kContext1)) ||
2079 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2080 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2081 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2082 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2083 return false;
2084 }
David Benjamina20e5352016-08-02 19:09:41 -04002085
David Benjamin0fef3052016-11-18 15:11:10 +09002086 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2087 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002088
David Benjamin0fef3052016-11-18 15:11:10 +09002089 bssl::UniquePtr<SSL_SESSION> session =
2090 CreateClientSession(client_ctx.get(), server_ctx.get());
2091 if (!session) {
2092 fprintf(stderr, "Error getting session.\n");
2093 return false;
2094 }
David Benjamina20e5352016-08-02 19:09:41 -04002095
David Benjamin0fef3052016-11-18 15:11:10 +09002096 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2097 true /* expect session reused */)) {
2098 fprintf(stderr, "Error resuming session.\n");
2099 return false;
2100 }
David Benjamina20e5352016-08-02 19:09:41 -04002101
David Benjamin0fef3052016-11-18 15:11:10 +09002102 // Change the session ID context.
2103 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2104 sizeof(kContext2))) {
2105 return false;
2106 }
David Benjamina20e5352016-08-02 19:09:41 -04002107
David Benjamin0fef3052016-11-18 15:11:10 +09002108 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2109 false /* expect session not reused */)) {
2110 fprintf(stderr, "Error connecting with a different context.\n");
2111 return false;
2112 }
David Benjamina933c382016-10-28 00:10:03 -04002113
David Benjamin0fef3052016-11-18 15:11:10 +09002114 // Change the session ID context back and install an SNI callback to switch
2115 // it.
2116 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2117 sizeof(kContext1))) {
2118 return false;
2119 }
David Benjamina933c382016-10-28 00:10:03 -04002120
David Benjamin0fef3052016-11-18 15:11:10 +09002121 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2122 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002123
David Benjamin0fef3052016-11-18 15:11:10 +09002124 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2125 false /* expect session not reused */)) {
2126 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2127 return false;
2128 }
David Benjamina933c382016-10-28 00:10:03 -04002129
David Benjamin0fef3052016-11-18 15:11:10 +09002130 // Switch the session ID context with the early callback instead.
2131 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2132 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2133 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002134
David Benjamin0fef3052016-11-18 15:11:10 +09002135 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2136 false /* expect session not reused */)) {
2137 fprintf(stderr,
2138 "Error connecting with a context switch on early callback.\n");
2139 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002140 }
2141
2142 return true;
2143}
2144
David Benjamin721e8b72016-08-03 13:13:17 -04002145static timeval g_current_time;
2146
2147static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2148 *out_clock = g_current_time;
2149}
2150
David Benjamin3c51d9b2016-11-01 17:50:42 -04002151static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2152 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2153 int encrypt) {
2154 static const uint8_t kZeros[16] = {0};
2155
2156 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002157 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002158 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002159 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002160 return 0;
2161 }
2162
2163 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2164 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2165 return -1;
2166 }
2167
2168 // Returning two from the callback in decrypt mode renews the
2169 // session in TLS 1.2 and below.
2170 return encrypt ? 1 : 2;
2171}
2172
David Benjamin123db572016-11-03 16:59:25 -04002173static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002174 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2175 return false;
2176 }
2177
David Benjamin123db572016-11-03 16:59:25 -04002178 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2179 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2180 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2181
David Benjamin9b63f292016-11-15 00:44:05 -05002182#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2183 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002184 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002185#else
2186 static const uint8_t kZeros[16] = {0};
2187 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002188 bssl::ScopedEVP_CIPHER_CTX ctx;
2189 int len1, len2;
2190 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2191 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2192 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2193 return false;
2194 }
2195
2196 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002197#endif
David Benjamin123db572016-11-03 16:59:25 -04002198
2199 bssl::UniquePtr<SSL_SESSION> server_session(
2200 SSL_SESSION_from_bytes(plaintext.get(), len));
2201 if (!server_session) {
2202 return false;
2203 }
2204
2205 *out = server_session->time;
2206 return true;
2207}
2208
David Benjamin0fef3052016-11-18 15:11:10 +09002209static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2210 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002211 bssl::UniquePtr<X509> cert = GetTestCertificate();
2212 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002213 if (!cert || !key) {
2214 return false;
2215 }
2216
David Benjamin0fef3052016-11-18 15:11:10 +09002217 for (bool server_test : std::vector<bool>{false, true}) {
2218 static const int kStartTime = 1000;
2219 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002220
David Benjamin0fef3052016-11-18 15:11:10 +09002221 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2222 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2223 if (!server_ctx || !client_ctx ||
2224 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2225 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2226 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2227 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2228 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2229 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2230 return false;
2231 }
2232
2233 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2234 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2235
2236 // Both client and server must enforce session timeouts.
2237 if (server_test) {
2238 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2239 } else {
2240 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2241 }
2242
2243 // Configure a ticket callback which renews tickets.
2244 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2245
2246 bssl::UniquePtr<SSL_SESSION> session =
2247 CreateClientSession(client_ctx.get(), server_ctx.get());
2248 if (!session) {
2249 fprintf(stderr, "Error getting session.\n");
2250 return false;
2251 }
2252
2253 // Advance the clock just behind the timeout.
2254 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
2255
2256 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2257 true /* expect session reused */)) {
2258 fprintf(stderr, "Error resuming session.\n");
2259 return false;
2260 }
2261
2262 // Advance the clock one more second.
2263 g_current_time.tv_sec++;
2264
2265 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2266 false /* expect session not reused */)) {
2267 fprintf(stderr, "Error resuming session.\n");
2268 return false;
2269 }
2270
2271 // Rewind the clock to before the session was minted.
2272 g_current_time.tv_sec = kStartTime - 1;
2273
2274 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2275 false /* expect session not reused */)) {
2276 fprintf(stderr, "Error resuming session.\n");
2277 return false;
2278 }
2279
2280 // SSL 3.0 cannot renew sessions.
2281 if (version == SSL3_VERSION) {
2282 continue;
2283 }
2284
2285 // Renew the session 10 seconds before expiration.
2286 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2287 bssl::UniquePtr<SSL_SESSION> new_session =
2288 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2289 if (!new_session) {
2290 fprintf(stderr, "Error renewing session.\n");
2291 return false;
2292 }
2293
2294 // This new session is not the same object as before.
2295 if (session.get() == new_session.get()) {
2296 fprintf(stderr, "New and old sessions alias.\n");
2297 return false;
2298 }
2299
2300 // Check the sessions have timestamps measured from issuance.
2301 long session_time = 0;
2302 if (server_test) {
2303 if (!GetServerTicketTime(&session_time, new_session.get())) {
2304 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002305 return false;
2306 }
David Benjamin0fef3052016-11-18 15:11:10 +09002307 } else {
2308 session_time = new_session->time;
2309 }
David Benjamin721e8b72016-08-03 13:13:17 -04002310
David Benjamin0fef3052016-11-18 15:11:10 +09002311 if (session_time != g_current_time.tv_sec) {
2312 fprintf(stderr, "New session is not measured from issuance.\n");
2313 return false;
2314 }
David Benjamin721e8b72016-08-03 13:13:17 -04002315
David Benjamin0fef3052016-11-18 15:11:10 +09002316 // The new session is usable just before the old expiration.
2317 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2318 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2319 new_session.get(),
2320 true /* expect session reused */)) {
2321 fprintf(stderr, "Error resuming renewed session.\n");
2322 return false;
2323 }
David Benjamin721e8b72016-08-03 13:13:17 -04002324
David Benjamin0fef3052016-11-18 15:11:10 +09002325 // Renewal does not extend the lifetime, so it is not usable beyond the
2326 // old expiration.
2327 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2328 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2329 new_session.get(),
2330 false /* expect session not reused */)) {
2331 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2332 return false;
David Benjamin1b22f852016-10-27 16:36:32 -04002333 }
David Benjamin721e8b72016-08-03 13:13:17 -04002334 }
2335
2336 return true;
2337}
2338
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002339static int SetSessionTimeoutCallback(SSL *ssl, void *arg) {
2340 long timeout = *(long *) arg;
2341 SSL_set_session_timeout(ssl, timeout);
2342 return 1;
2343}
2344
2345static bool TestSessionTimeoutCertCallback(bool is_dtls,
2346 const SSL_METHOD *method,
2347 uint16_t version) {
2348 static const int kStartTime = 1000;
2349 g_current_time.tv_sec = kStartTime;
2350
2351 bssl::UniquePtr<X509> cert = GetTestCertificate();
2352 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2353 if (!cert || !key) {
2354 return false;
2355 }
2356
2357 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2358 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2359 if (!server_ctx || !client_ctx ||
2360 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2361 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2362 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2363 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2364 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2365 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2366 return false;
2367 }
2368
2369 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2370 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2371
2372 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2373
2374 long timeout = 25;
2375 SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
2376
2377 bssl::UniquePtr<SSL_SESSION> session =
2378 CreateClientSession(client_ctx.get(), server_ctx.get());
2379 if (!session) {
2380 fprintf(stderr, "Error getting session.\n");
2381 return false;
2382 }
2383
2384 // Advance the clock just behind the timeout.
2385 g_current_time.tv_sec += timeout - 1;
2386
2387 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2388 true /* expect session reused */)) {
2389 fprintf(stderr, "Error resuming session.\n");
2390 return false;
2391 }
2392
2393 // Advance the clock one more second.
2394 g_current_time.tv_sec++;
2395
2396 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2397 false /* expect session not reused */)) {
2398 fprintf(stderr, "Error resuming session.\n");
2399 return false;
2400 }
2401
2402 // Set session timeout to 0 to disable resumption.
2403 timeout = 0;
2404 g_current_time.tv_sec = kStartTime;
2405
2406 bssl::UniquePtr<SSL_SESSION> not_resumable_session =
2407 CreateClientSession(client_ctx.get(), server_ctx.get());
2408 if (!not_resumable_session) {
2409 fprintf(stderr, "Error getting session.\n");
2410 return false;
2411 }
2412
2413 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2414 not_resumable_session.get(),
2415 false /* expect session not reused */)) {
2416 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2417 return false;
2418 }
2419
2420 // Set both context and connection (via callback) default session timeout.
2421 // The connection one is the one that ends up being used.
2422 timeout = 25;
2423 g_current_time.tv_sec = kStartTime;
2424
2425 SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
2426
2427 bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
2428 CreateClientSession(client_ctx.get(), server_ctx.get());
2429 if (!ctx_and_cb_session) {
2430 fprintf(stderr, "Error getting session.\n");
2431 return false;
2432 }
2433
2434 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2435 ctx_and_cb_session.get(),
2436 true /* expect session reused */)) {
2437 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2438 return false;
2439 }
2440
2441 // Advance the clock just behind the timeout.
2442 g_current_time.tv_sec += timeout - 1;
2443
2444 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2445 ctx_and_cb_session.get(),
2446 true /* expect session reused */)) {
2447 fprintf(stderr, "Error resuming session.\n");
2448 return false;
2449 }
2450
2451 // Advance the clock one more second.
2452 g_current_time.tv_sec++;
2453
2454 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2455 ctx_and_cb_session.get(),
2456 false /* expect session not reused */)) {
2457 fprintf(stderr, "Error resuming session.\n");
2458 return false;
2459 }
2460
2461 return true;
2462}
2463
David Benjamin0fc37ef2016-08-17 15:29:46 -04002464static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2465 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2466 SSL_set_SSL_CTX(ssl, ctx);
2467 return SSL_TLSEXT_ERR_OK;
2468}
2469
David Benjamin0fef3052016-11-18 15:11:10 +09002470static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2471 uint16_t version) {
2472 // SSL 3.0 lacks extensions.
2473 if (version == SSL3_VERSION) {
2474 return true;
2475 }
2476
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002477 bssl::UniquePtr<X509> cert = GetTestCertificate();
2478 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2479 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2480 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002481 if (!cert || !key || !cert2 || !key2) {
2482 return false;
2483 }
2484
David Benjamin0fef3052016-11-18 15:11:10 +09002485 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2486 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002487
David Benjamin0fef3052016-11-18 15:11:10 +09002488 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2489 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2490 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2491 if (!server_ctx || !server_ctx2 || !client_ctx ||
2492 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2493 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2494 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2495 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2496 // Historically signing preferences would be lost in some cases with the
2497 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2498 // this doesn't happen when |version| is TLS 1.2, configure the private
2499 // key to only sign SHA-256.
2500 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2501 1) ||
2502 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2503 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2504 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2505 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2506 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2507 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2508 return false;
2509 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002510
David Benjamin0fef3052016-11-18 15:11:10 +09002511 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2512 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002513
David Benjamin0fef3052016-11-18 15:11:10 +09002514 bssl::UniquePtr<SSL> client, server;
2515 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2516 server_ctx.get(), nullptr)) {
2517 fprintf(stderr, "Handshake failed.\n");
2518 return false;
2519 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002520
David Benjamin0fef3052016-11-18 15:11:10 +09002521 // The client should have received |cert2|.
2522 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2523 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2524 fprintf(stderr, "Incorrect certificate received.\n");
2525 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002526 }
2527
2528 return true;
2529}
2530
David Benjamin731058e2016-12-03 23:15:13 -05002531static int SetMaxVersion(const SSL_CLIENT_HELLO *client_hello) {
2532 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002533 return -1;
2534 }
2535
David Benjamin99620572016-08-30 00:35:36 -04002536 return 1;
2537}
2538
2539// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2540// maximum version.
2541static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002542 bssl::UniquePtr<X509> cert = GetTestCertificate();
2543 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2544 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2545 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002546 if (!cert || !key || !server_ctx || !client_ctx ||
2547 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002548 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002549 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2550 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002551 return false;
2552 }
2553
David Benjamin99620572016-08-30 00:35:36 -04002554 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2555
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002556 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002557 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2558 server_ctx.get(), nullptr)) {
2559 return false;
2560 }
2561
2562 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2563 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2564 return false;
2565 }
2566
2567 return true;
2568}
2569
David Benjamin2dc02042016-09-19 19:57:37 -04002570static bool TestSetVersion() {
2571 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2572 if (!ctx) {
2573 return false;
2574 }
2575
David Benjamine4706902016-09-20 15:12:23 -04002576 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2577 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2578 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2579 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002580 fprintf(stderr, "Could not set valid TLS version.\n");
2581 return false;
2582 }
2583
David Benjamine4706902016-09-20 15:12:23 -04002584 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2585 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2586 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2587 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2588 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2589 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002590 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2591 return false;
2592 }
2593
David Benjamine34bcc92016-09-21 16:53:09 -04002594 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2595 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2596 fprintf(stderr, "Could not set default TLS version.\n");
2597 return false;
2598 }
2599
2600 if (ctx->min_version != SSL3_VERSION ||
2601 ctx->max_version != TLS1_2_VERSION) {
2602 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2603 ctx->min_version, ctx->max_version);
2604 return false;
2605 }
2606
David Benjamin2dc02042016-09-19 19:57:37 -04002607 ctx.reset(SSL_CTX_new(DTLS_method()));
2608 if (!ctx) {
2609 return false;
2610 }
2611
David Benjamine4706902016-09-20 15:12:23 -04002612 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2613 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2614 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2615 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002616 fprintf(stderr, "Could not set valid DTLS version.\n");
2617 return false;
2618 }
2619
David Benjamine4706902016-09-20 15:12:23 -04002620 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2621 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2622 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2623 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2624 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2625 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2626 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2627 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002628 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2629 return false;
2630 }
2631
David Benjamine34bcc92016-09-21 16:53:09 -04002632 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2633 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2634 fprintf(stderr, "Could not set default DTLS version.\n");
2635 return false;
2636 }
2637
2638 if (ctx->min_version != TLS1_1_VERSION ||
2639 ctx->max_version != TLS1_2_VERSION) {
2640 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2641 ctx->min_version, ctx->max_version);
2642 return false;
2643 }
2644
David Benjamin2dc02042016-09-19 19:57:37 -04002645 return true;
2646}
2647
David Benjamin458334a2016-12-15 13:53:25 -05002648static const char *GetVersionName(uint16_t version) {
2649 switch (version) {
2650 case SSL3_VERSION:
2651 return "SSLv3";
2652 case TLS1_VERSION:
2653 return "TLSv1";
2654 case TLS1_1_VERSION:
2655 return "TLSv1.1";
2656 case TLS1_2_VERSION:
2657 return "TLSv1.2";
2658 case TLS1_3_VERSION:
2659 return "TLSv1.3";
2660 case DTLS1_VERSION:
2661 return "DTLSv1";
2662 case DTLS1_2_VERSION:
2663 return "DTLSv1.2";
2664 default:
2665 return "???";
2666 }
2667}
2668
David Benjamin0fef3052016-11-18 15:11:10 +09002669static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2670 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002671 bssl::UniquePtr<X509> cert = GetTestCertificate();
2672 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2673 if (!cert || !key) {
2674 return false;
2675 }
2676
David Benjamin0fef3052016-11-18 15:11:10 +09002677 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2678 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2679 bssl::UniquePtr<SSL> client, server;
2680 if (!server_ctx || !client_ctx ||
2681 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2682 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2683 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2684 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2685 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2686 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2687 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2688 server_ctx.get(), nullptr /* no session */)) {
2689 fprintf(stderr, "Failed to connect.\n");
2690 return false;
2691 }
David Benjamincb18ac22016-09-27 14:09:15 -04002692
David Benjamin0fef3052016-11-18 15:11:10 +09002693 if (SSL_version(client.get()) != version ||
2694 SSL_version(server.get()) != version) {
2695 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2696 SSL_version(client.get()), SSL_version(server.get()), version);
2697 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002698 }
2699
David Benjamin458334a2016-12-15 13:53:25 -05002700 // Test the version name is reported as expected.
2701 const char *version_name = GetVersionName(version);
2702 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2703 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2704 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2705 SSL_get_version(client.get()), SSL_get_version(server.get()),
2706 version_name);
2707 return false;
2708 }
2709
2710 // Test SSL_SESSION reports the same name.
2711 const char *client_name =
2712 SSL_SESSION_get_version(SSL_get_session(client.get()));
2713 const char *server_name =
2714 SSL_SESSION_get_version(SSL_get_session(server.get()));
2715 if (strcmp(version_name, client_name) != 0 ||
2716 strcmp(version_name, server_name) != 0) {
2717 fprintf(stderr,
2718 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2719 client_name, server_name, version_name);
2720 return false;
2721 }
2722
David Benjamincb18ac22016-09-27 14:09:15 -04002723 return true;
2724}
2725
David Benjamin9ef31f02016-10-31 18:01:13 -04002726// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2727// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002728static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2729 uint16_t version) {
2730 // SSL 3.0 lacks extensions.
2731 if (version == SSL3_VERSION) {
2732 return true;
2733 }
2734
David Benjamin9ef31f02016-10-31 18:01:13 -04002735 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2736
2737 bssl::UniquePtr<X509> cert = GetTestCertificate();
2738 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2739 if (!cert || !key) {
2740 return false;
2741 }
2742
David Benjamin0fef3052016-11-18 15:11:10 +09002743 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2744 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2745 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2746 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2747 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2748 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2749 0) {
2750 return false;
2751 }
2752
2753 // The ALPN callback does not fail the handshake on error, so have the
2754 // callback write a boolean.
2755 std::pair<uint16_t, bool> callback_state(version, false);
2756 SSL_CTX_set_alpn_select_cb(
2757 ctx.get(),
2758 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2759 unsigned in_len, void *arg) -> int {
2760 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2761 if (SSL_get_pending_cipher(ssl) != nullptr &&
2762 SSL_version(ssl) == state->first) {
2763 state->second = true;
2764 }
2765 return SSL_TLSEXT_ERR_NOACK;
2766 },
2767 &callback_state);
2768
2769 bssl::UniquePtr<SSL> client, server;
2770 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2771 nullptr /* no session */)) {
2772 return false;
2773 }
2774
2775 if (!callback_state.second) {
2776 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2777 return false;
2778 }
2779
2780 return true;
2781}
2782
David Benjaminb79cc842016-12-07 15:57:14 -05002783static bool TestSSLClearSessionResumption(bool is_dtls,
2784 const SSL_METHOD *method,
2785 uint16_t version) {
2786 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2787 // API pattern.
2788 if (version == TLS1_3_VERSION) {
2789 return true;
2790 }
2791
2792 bssl::UniquePtr<X509> cert = GetTestCertificate();
2793 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2794 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2795 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2796 if (!cert || !key || !server_ctx || !client_ctx ||
2797 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2798 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2799 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2800 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2801 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2802 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2803 return false;
2804 }
2805
2806 // Connect a client and a server.
2807 bssl::UniquePtr<SSL> client, server;
2808 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2809 server_ctx.get(), nullptr /* no session */)) {
2810 return false;
2811 }
2812
2813 if (SSL_session_reused(client.get()) ||
2814 SSL_session_reused(server.get())) {
2815 fprintf(stderr, "Session unexpectedly reused.\n");
2816 return false;
2817 }
2818
2819 // Reset everything.
2820 if (!SSL_clear(client.get()) ||
2821 !SSL_clear(server.get())) {
2822 fprintf(stderr, "SSL_clear failed.\n");
2823 return false;
2824 }
2825
2826 // Attempt to connect a second time.
2827 if (!CompleteHandshakes(client.get(), server.get())) {
2828 fprintf(stderr, "Could not reuse SSL objects.\n");
2829 return false;
2830 }
2831
2832 // |SSL_clear| should implicitly offer the previous session to the server.
2833 if (!SSL_session_reused(client.get()) ||
2834 !SSL_session_reused(server.get())) {
2835 fprintf(stderr, "Session was not reused in second try.\n");
2836 return false;
2837 }
2838
2839 return true;
2840}
2841
David Benjamin1444c3a2016-12-20 17:23:11 -05002842static bool ChainsEqual(STACK_OF(X509) *chain,
2843 const std::vector<X509 *> &expected) {
2844 if (sk_X509_num(chain) != expected.size()) {
2845 return false;
2846 }
2847
2848 for (size_t i = 0; i < expected.size(); i++) {
2849 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2850 return false;
2851 }
2852 }
2853
2854 return true;
2855}
2856
2857static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2858 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002859 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2860 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2861 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2862 if (!cert || !intermediate || !key) {
2863 return false;
2864 }
2865
2866 // Configure both client and server to accept any certificate. Add
2867 // |intermediate| to the cert store.
2868 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2869 if (!ctx ||
2870 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2871 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2872 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2873 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2874 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2875 intermediate.get())) {
2876 return false;
2877 }
2878 SSL_CTX_set_verify(
2879 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2880 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2881
2882 // By default, the client and server should each only send the leaf.
2883 bssl::UniquePtr<SSL> client, server;
2884 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2885 nullptr /* no session */)) {
2886 return false;
2887 }
2888
2889 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2890 fprintf(stderr, "Client-received chain did not match.\n");
2891 return false;
2892 }
2893
2894 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2895 fprintf(stderr, "Server-received chain did not match.\n");
2896 return false;
2897 }
2898
2899 // If auto-chaining is enabled, then the intermediate is sent.
2900 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2901 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2902 nullptr /* no session */)) {
2903 return false;
2904 }
2905
2906 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2907 {cert.get(), intermediate.get()})) {
2908 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2909 return false;
2910 }
2911
2912 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2913 {cert.get(), intermediate.get()})) {
2914 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2915 return false;
2916 }
2917
2918 // Auto-chaining does not override explicitly-configured intermediates.
2919 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2920 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2921 nullptr /* no session */)) {
2922 return false;
2923 }
2924
2925 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2926 {cert.get(), cert.get()})) {
2927 fprintf(stderr,
2928 "Client-received chain did not match (auto-chaining, explicit "
2929 "intermediate).\n");
2930 return false;
2931 }
2932
2933 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2934 {cert.get(), cert.get()})) {
2935 fprintf(stderr,
2936 "Server-received chain did not match (auto-chaining, explicit "
2937 "intermediate).\n");
2938 return false;
2939 }
2940
2941 return true;
2942}
2943
David Benjamin48063c22017-01-01 23:56:36 -05002944static bool ExpectBadWriteRetry() {
2945 int err = ERR_get_error();
2946 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2947 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2948 char buf[ERR_ERROR_STRING_BUF_LEN];
2949 ERR_error_string_n(err, buf, sizeof(buf));
2950 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2951 return false;
2952 }
2953
2954 if (ERR_peek_error() != 0) {
2955 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2956 return false;
2957 }
2958
2959 return true;
2960}
2961
2962static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
2963 uint16_t version) {
2964 if (is_dtls) {
2965 return true;
2966 }
2967
2968 for (bool enable_partial_write : std::vector<bool>{false, true}) {
2969 // Connect a client and server.
2970 bssl::UniquePtr<X509> cert = GetTestCertificate();
2971 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2972 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2973 bssl::UniquePtr<SSL> client, server;
2974 if (!cert || !key || !ctx ||
2975 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2976 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2977 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2978 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2979 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2980 nullptr /* no session */)) {
2981 return false;
2982 }
2983
2984 if (enable_partial_write) {
2985 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
2986 }
2987
2988 // Write without reading until the buffer is full and we have an unfinished
2989 // write. Keep a count so we may reread it again later. "hello!" will be
2990 // written in two chunks, "hello" and "!".
2991 char data[] = "hello!";
2992 static const int kChunkLen = 5; // The length of "hello".
2993 unsigned count = 0;
2994 for (;;) {
2995 int ret = SSL_write(client.get(), data, kChunkLen);
2996 if (ret <= 0) {
2997 int err = SSL_get_error(client.get(), ret);
2998 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
2999 break;
3000 }
3001 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
3002 return false;
3003 }
3004
3005 if (ret != 5) {
3006 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
3007 return false;
3008 }
3009
3010 count++;
3011 }
3012
3013 // Retrying with the same parameters is legal.
3014 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
3015 SSL_ERROR_WANT_WRITE) {
3016 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3017 return false;
3018 }
3019
3020 // Retrying with the same buffer but shorter length is not legal.
3021 if (SSL_get_error(client.get(),
3022 SSL_write(client.get(), data, kChunkLen - 1)) !=
3023 SSL_ERROR_SSL ||
3024 !ExpectBadWriteRetry()) {
3025 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3026 return false;
3027 }
3028
3029 // Retrying with a different buffer pointer is not legal.
3030 char data2[] = "hello";
3031 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
3032 kChunkLen)) != SSL_ERROR_SSL ||
3033 !ExpectBadWriteRetry()) {
3034 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3035 return false;
3036 }
3037
3038 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
3039 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3040 if (SSL_get_error(client.get(),
3041 SSL_write(client.get(), data2, kChunkLen)) !=
3042 SSL_ERROR_WANT_WRITE) {
3043 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3044 return false;
3045 }
3046
3047 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
3048 if (SSL_get_error(client.get(),
3049 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3050 SSL_ERROR_SSL ||
3051 !ExpectBadWriteRetry()) {
3052 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3053 return false;
3054 }
3055
3056 // Retrying with a larger buffer is legal.
3057 if (SSL_get_error(client.get(),
3058 SSL_write(client.get(), data, kChunkLen + 1)) !=
3059 SSL_ERROR_WANT_WRITE) {
3060 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3061 return false;
3062 }
3063
3064 // Drain the buffer.
3065 char buf[20];
3066 for (unsigned i = 0; i < count; i++) {
3067 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3068 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3069 fprintf(stderr, "Failed to read initial records.\n");
3070 return false;
3071 }
3072 }
3073
3074 // Now that there is space, a retry with a larger buffer should flush the
3075 // pending record, skip over that many bytes of input (on assumption they
3076 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3077 // is set, this will complete in two steps.
3078 char data3[] = "_____!";
3079 if (enable_partial_write) {
3080 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3081 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3082 fprintf(stderr, "SSL_write retry failed.\n");
3083 return false;
3084 }
3085 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3086 fprintf(stderr, "SSL_write retry failed.\n");
3087 return false;
3088 }
3089
3090 // Check the last write was correct. The data will be spread over two
3091 // records, so SSL_read returns twice.
3092 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3093 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3094 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3095 buf[0] != '!') {
3096 fprintf(stderr, "Failed to read write retry.\n");
3097 return false;
3098 }
3099 }
3100
3101 return true;
3102}
3103
David Benjamin0fef3052016-11-18 15:11:10 +09003104static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3105 const SSL_METHOD *method,
3106 uint16_t version)) {
3107 static uint16_t kTLSVersions[] = {
3108 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
3109 TLS1_2_VERSION, TLS1_3_VERSION,
3110 };
3111
3112 static uint16_t kDTLSVersions[] = {
3113 DTLS1_VERSION, DTLS1_2_VERSION,
3114 };
3115
David Benjamin9ef31f02016-10-31 18:01:13 -04003116 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003117 if (!test_func(false, TLS_method(), version)) {
3118 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003119 return false;
3120 }
David Benjamin0fef3052016-11-18 15:11:10 +09003121 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003122
David Benjamin0fef3052016-11-18 15:11:10 +09003123 for (uint16_t version : kDTLSVersions) {
3124 if (!test_func(true, DTLS_method(), version)) {
3125 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003126 return false;
3127 }
3128 }
3129
3130 return true;
3131}
3132
David Benjamin96628432017-01-19 19:05:47 -05003133// TODO(davidben): Convert this file to GTest properly.
3134TEST(SSLTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -07003135 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003136 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003137 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3138 !TestSSL_SESSIONEncoding(kCustomSession) ||
3139 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3140 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3141 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3142 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003143 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07003144 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
3145 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
3146 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3147 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3148 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3149 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3150 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3151 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3152 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003153 // Test the padding extension at TLS 1.2.
3154 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3155 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3156 // will be no PSK binder after the padding extension.
3157 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3158 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3159 // will be a PSK binder after the padding extension.
3160 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003161 !TestClientCAList() ||
3162 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003163 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003164 !ForEachVersion(TestOneSidedShutdown) ||
Steven Valdez87eab492016-06-27 16:34:59 -04003165 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04003166 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04003167 !TestSetBIO() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003168 !ForEachVersion(TestGetPeerCertificate) ||
3169 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003170 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003171 !ForEachVersion(TestSessionIDContext) ||
3172 !ForEachVersion(TestSessionTimeout) ||
Alessandro Ghedinibf483642016-11-22 18:56:46 +00003173 !ForEachVersion(TestSessionTimeoutCertCallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003174 !ForEachVersion(TestSNICallback) ||
David Benjamin2dc02042016-09-19 19:57:37 -04003175 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04003176 !TestSetVersion() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003177 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003178 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003179 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003180 !ForEachVersion(TestAutoChain) ||
3181 !ForEachVersion(TestSSLWriteRetry)) {
Brian Smith83a82982015-04-09 16:21:10 -10003182 ERR_print_errors_fp(stderr);
David Benjamin96628432017-01-19 19:05:47 -05003183 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003184 }
David Benjamin2e521212014-07-16 14:37:51 -04003185}