blob: 5884d930c6059eba11ccbf32b3b4f235ce389c8c [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040026#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040027#include <openssl/err.h>
David Benjaminde942382016-02-11 12:02:01 -050028#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040029#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050031#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032
Steven Valdez87eab492016-06-27 16:34:59 -040033#include "internal.h"
Adam Langleyd2b5af52016-07-12 08:03:59 -070034#include "test/scoped_types.h"
Steven Valdezcb966542016-08-17 16:56:14 -040035#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020036#include "../crypto/test/test_util.h"
37
David Benjamin721e8b72016-08-03 13:13:17 -040038#if defined(OPENSSL_WINDOWS)
39/* Windows defines struct timeval in winsock2.h. */
40OPENSSL_MSVC_PRAGMA(warning(push, 3))
41#include <winsock2.h>
42OPENSSL_MSVC_PRAGMA(warning(pop))
43#else
44#include <sys/time.h>
45#endif
46
David Benjamin1d77e562015-03-22 17:22:08 -040047
48struct ExpectedCipher {
49 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040050 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040051};
David Benjaminbb0a17c2014-09-20 15:35:39 -040052
David Benjamin1d77e562015-03-22 17:22:08 -040053struct CipherTest {
54 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040055 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050056 // The list of expected ciphers, in order.
57 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040058};
David Benjaminbb0a17c2014-09-20 15:35:39 -040059
David Benjaminfb974e62015-12-16 19:34:22 -050060static const CipherTest kCipherTests[] = {
61 // Selecting individual ciphers should work.
62 {
63 "ECDHE-ECDSA-CHACHA20-POLY1305:"
64 "ECDHE-RSA-CHACHA20-POLY1305:"
65 "ECDHE-ECDSA-AES128-GCM-SHA256:"
66 "ECDHE-RSA-AES128-GCM-SHA256",
67 {
68 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
69 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
70 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
71 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
72 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
73 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
74 },
75 },
76 // + reorders selected ciphers to the end, keeping their relative order.
77 {
78 "ECDHE-ECDSA-CHACHA20-POLY1305:"
79 "ECDHE-RSA-CHACHA20-POLY1305:"
80 "ECDHE-ECDSA-AES128-GCM-SHA256:"
81 "ECDHE-RSA-AES128-GCM-SHA256:"
82 "+aRSA",
83 {
84 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
85 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
86 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
87 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
88 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
89 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
90 },
91 },
92 // ! banishes ciphers from future selections.
93 {
94 "!aRSA:"
95 "ECDHE-ECDSA-CHACHA20-POLY1305:"
96 "ECDHE-RSA-CHACHA20-POLY1305:"
97 "ECDHE-ECDSA-AES128-GCM-SHA256:"
98 "ECDHE-RSA-AES128-GCM-SHA256",
99 {
100 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
101 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
102 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
103 },
104 },
105 // Multiple masks can be ANDed in a single rule.
106 {
107 "kRSA+AESGCM+AES128",
108 {
109 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
110 },
111 },
112 // - removes selected ciphers, but preserves their order for future
113 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
114 // ECDHE_RSA.
115 {
116 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
117 "AESGCM+AES128+aRSA",
118 {
119 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
120 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
121 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
122 },
123 },
124 // Unknown selectors are no-ops.
125 {
126 "ECDHE-ECDSA-CHACHA20-POLY1305:"
127 "ECDHE-RSA-CHACHA20-POLY1305:"
128 "ECDHE-ECDSA-AES128-GCM-SHA256:"
129 "ECDHE-RSA-AES128-GCM-SHA256:"
130 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
131 {
132 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
133 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
134 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
135 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
136 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
137 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
138 },
139 },
140 // Square brackets specify equi-preference groups.
141 {
142 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
143 "[ECDHE-RSA-CHACHA20-POLY1305]:"
144 "ECDHE-RSA-AES128-GCM-SHA256",
145 {
146 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
147 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
148 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
149 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
150 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
151 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
152 },
153 },
154 // @STRENGTH performs a stable strength-sort of the selected ciphers and
155 // only the selected ciphers.
156 {
157 // To simplify things, banish all but {ECDHE_RSA,RSA} x
158 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
159 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
160 // Order some ciphers backwards by strength.
161 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
162 // Select ECDHE ones and sort them by strength. Ties should resolve
163 // based on the order above.
164 "kECDHE:@STRENGTH:-ALL:"
165 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
166 // by strength. Then RSA, backwards by strength.
167 "aRSA",
168 {
169 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
170 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
171 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
172 {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
173 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
174 {SSL3_CK_RSA_RC4_128_SHA, 0},
175 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
176 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
177 },
178 },
179 // Exact ciphers may not be used in multi-part rules; they are treated
180 // as unknown aliases.
181 {
182 "ECDHE-ECDSA-AES128-GCM-SHA256:"
183 "ECDHE-RSA-AES128-GCM-SHA256:"
184 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
185 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
186 {
187 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
188 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
189 },
190 },
191 // SSLv3 matches everything that existed before TLS 1.2.
192 {
193 "AES128-SHA:AES128-SHA256:!SSLv3",
194 {
195 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
196 },
197 },
198 // TLSv1.2 matches everything added in TLS 1.2.
199 {
200 "AES128-SHA:AES128-SHA256:!TLSv1.2",
201 {
202 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
203 },
204 },
205 // The two directives have no intersection.
206 {
207 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
208 {
209 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
210 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
211 },
212 },
213 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
214 // name and not an alias. It may not be used in a multipart rule. (That the
215 // shared name works is covered by the standard tests.)
216 {
217 "ECDHE-ECDSA-CHACHA20-POLY1305:"
218 "ECDHE-RSA-CHACHA20-POLY1305:"
219 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
220 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
221 {
222 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
223 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
224 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
225 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
226 },
227 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400228};
229
230static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400231 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
233 "RSA]",
234 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400237 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400238 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "",
241 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400242 // COMPLEMENTOFDEFAULT is empty.
243 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400244 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400245 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400246 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400247 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
248 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
249 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
250 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400251};
252
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700253static const char *kMustNotIncludeNull[] = {
254 "ALL",
255 "DEFAULT",
256 "ALL:!eNULL",
257 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500258 "MEDIUM",
259 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700260 "FIPS",
261 "SHA",
262 "SHA1",
263 "RSA",
264 "SSLv3",
265 "TLSv1",
266 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700267};
268
Matt Braithwaite053931e2016-05-25 12:06:05 -0700269static const char *kMustNotIncludeCECPQ1[] = {
270 "ALL",
271 "DEFAULT",
272 "MEDIUM",
273 "HIGH",
274 "FIPS",
275 "SHA",
276 "SHA1",
277 "SHA256",
278 "SHA384",
279 "RSA",
280 "SSLv3",
281 "TLSv1",
282 "TLSv1.2",
283 "aRSA",
284 "RSA",
285 "aECDSA",
286 "ECDSA",
287 "AES",
288 "AES128",
289 "AES256",
290 "AESGCM",
291 "CHACHA20",
292};
293
David Benjamin1d77e562015-03-22 17:22:08 -0400294static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
295 bool in_group = false;
296 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400297 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
298 if (!in_group && list->in_group_flags[i]) {
299 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400300 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400301 }
302 fprintf(stderr, "\t");
303 if (in_group) {
304 fprintf(stderr, " ");
305 }
306 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
307 if (in_group && !list->in_group_flags[i]) {
308 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400309 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400310 }
311 }
312}
313
David Benjaminfb974e62015-12-16 19:34:22 -0500314static bool TestCipherRule(const CipherTest &t) {
David Benjamin1d77e562015-03-22 17:22:08 -0400315 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
316 if (!ctx) {
317 return false;
David Benjamin65226252015-02-05 16:49:47 -0500318 }
319
David Benjaminfb974e62015-12-16 19:34:22 -0500320 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
321 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400322 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400323 }
324
David Benjamin1d77e562015-03-22 17:22:08 -0400325 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500326 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
327 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
328 PrintCipherPreferenceList(ctx->cipher_list);
329 return false;
330 }
331
332 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400333 const SSL_CIPHER *cipher =
334 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500335 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
336 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
337 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400338 PrintCipherPreferenceList(ctx->cipher_list);
339 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400340 }
341 }
342
David Benjamin1d77e562015-03-22 17:22:08 -0400343 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400344}
345
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700346static bool TestRuleDoesNotIncludeNull(const char *rule) {
347 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
348 if (!ctx) {
349 return false;
350 }
351 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
352 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
353 return false;
354 }
355 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
356 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
357 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
358 return false;
359 }
360 }
361 return true;
362}
363
Matt Braithwaite053931e2016-05-25 12:06:05 -0700364static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
365 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
366 if (!ctx) {
367 return false;
368 }
369 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
370 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
371 return false;
372 }
373 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
374 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
375 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
376 return false;
377 }
378 }
379 return true;
380}
381
David Benjamin1d77e562015-03-22 17:22:08 -0400382static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500383 for (const CipherTest &test : kCipherTests) {
384 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400385 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400386 }
387 }
388
David Benjaminfb974e62015-12-16 19:34:22 -0500389 for (const char *rule : kBadRules) {
David Benjamin1d77e562015-03-22 17:22:08 -0400390 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
391 if (!ctx) {
392 return false;
David Benjamin65226252015-02-05 16:49:47 -0500393 }
David Benjaminfb974e62015-12-16 19:34:22 -0500394 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
395 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400396 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400397 }
398 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400399 }
400
David Benjaminfb974e62015-12-16 19:34:22 -0500401 for (const char *rule : kMustNotIncludeNull) {
402 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700403 return false;
404 }
405 }
406
Matt Braithwaite053931e2016-05-25 12:06:05 -0700407 for (const char *rule : kMustNotIncludeCECPQ1) {
408 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
409 return false;
410 }
411 }
412
David Benjamin1d77e562015-03-22 17:22:08 -0400413 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400414}
David Benjamin2e521212014-07-16 14:37:51 -0400415
Adam Langley10f97f32016-07-12 08:09:33 -0700416// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
417// s_client -sess_out.
418static const char kOpenSSLSession[] =
419 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
420 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
421 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
422 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
423 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
424 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
425 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
426 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
427 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
428 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
429 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
430 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
431 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
432 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
433 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
434 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
435 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
436 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
437 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
438 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
439 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
440 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
441 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
442 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
443 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
444 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
445 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
446 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
447 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
448 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
449 "i4gv7Y5oliyn";
450
451// kCustomSession is a custom serialized SSL_SESSION generated by
452// filling in missing fields from |kOpenSSLSession|. This includes
453// providing |peer_sha256|, so |peer| is not serialized.
454static const char kCustomSession[] =
455 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
456 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
457 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
458 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
459 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
460 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
461 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
462 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
463
464// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
465static const char kBoringSSLSession[] =
466 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
467 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
468 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
469 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
470 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
471 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
472 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
473 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
474 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
475 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
476 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
477 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
478 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
479 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
480 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
481 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
482 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
483 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
484 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
485 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
486 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
487 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
488 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
489 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
490 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
491 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
492 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
493 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
494 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
495 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
496 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
497 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
498 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
499 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
500 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
501 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
502 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
503 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
504 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
505 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
506 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
507 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
508 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
509 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
510 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
511 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
512 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
513 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
514 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
515 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
516 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
517 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
518 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
519 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
520 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
521 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
522 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
523 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
524 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
525 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
526 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
527 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
528 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
529 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
530 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
531 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
532 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
533 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
534 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
535 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
536 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
537 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
538 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
539 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
540 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
541 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
542 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
543 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
544 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
545 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
546 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
547 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
548 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
549 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
550 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
551 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
552 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
553 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
554 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
555 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
556 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
557 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
558 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
559 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
560 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
561
562// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
563// the final (optional) element of |kCustomSession| with tag number 30.
564static const char kBadSessionExtraField[] =
565 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
566 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
567 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
568 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
569 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
570 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
571 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
572 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
573
574// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
575// the version of |kCustomSession| with 2.
576static const char kBadSessionVersion[] =
577 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
578 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
579 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
580 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
581 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
582 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
583 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
584 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
585
586// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
587// appended.
588static const char kBadSessionTrailingData[] =
589 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
590 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
591 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
592 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
593 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
594 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
595 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
596 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
597
David Benjamin1d77e562015-03-22 17:22:08 -0400598static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400599 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400600 if (!EVP_DecodedLength(&len, strlen(in))) {
601 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400602 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400603 }
604
David Benjamin1d77e562015-03-22 17:22:08 -0400605 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800606 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400607 strlen(in))) {
608 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400609 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400610 }
David Benjamin1d77e562015-03-22 17:22:08 -0400611 out->resize(len);
612 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400613}
614
David Benjamin1d77e562015-03-22 17:22:08 -0400615static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400616 const uint8_t *cptr;
617 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400618
David Benjamin1d77e562015-03-22 17:22:08 -0400619 // Decode the input.
620 std::vector<uint8_t> input;
621 if (!DecodeBase64(&input, input_b64)) {
622 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400623 }
624
David Benjamin1d77e562015-03-22 17:22:08 -0400625 // Verify the SSL_SESSION decodes.
David Benjaminef14b2d2015-11-11 14:01:27 -0800626 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400627 if (!session) {
628 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400629 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400630 }
631
David Benjamin1d77e562015-03-22 17:22:08 -0400632 // Verify the SSL_SESSION encoding round-trips.
633 size_t encoded_len;
Adam Langley10f97f32016-07-12 08:09:33 -0700634 ScopedOpenSSLBytes encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400635 uint8_t *encoded_raw;
636 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400637 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400638 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400639 }
David Benjamin1d77e562015-03-22 17:22:08 -0400640 encoded.reset(encoded_raw);
641 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800642 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400643 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200644 hexdump(stderr, "Before: ", input.data(), input.size());
645 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400646 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400647 }
David Benjamin3cac4502014-10-21 01:46:30 -0400648
David Benjaminfd67aa82015-06-15 19:41:48 -0400649 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800650 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400651 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800652 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400653 fprintf(stderr, "d2i_SSL_SESSION failed\n");
654 return false;
655 }
656
David Benjamin1d77e562015-03-22 17:22:08 -0400657 // Verify the SSL_SESSION encoding round-trips via the legacy API.
658 int len = i2d_SSL_SESSION(session.get(), NULL);
659 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400660 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400661 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400662 }
663
David Benjamin1d77e562015-03-22 17:22:08 -0400664 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
665 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400666 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400667 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400668 }
David Benjamin1d77e562015-03-22 17:22:08 -0400669
670 ptr = encoded.get();
671 len = i2d_SSL_SESSION(session.get(), &ptr);
672 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400673 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400674 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400675 }
David Benjamin1d77e562015-03-22 17:22:08 -0400676 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400677 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400678 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400679 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800680 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400681 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400682 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400683 }
684
David Benjamin1d77e562015-03-22 17:22:08 -0400685 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400686}
687
David Benjaminf297e022015-05-28 19:55:29 -0400688static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
689 std::vector<uint8_t> input;
690 if (!DecodeBase64(&input, input_b64)) {
691 return false;
692 }
693
694 // Verify that the SSL_SESSION fails to decode.
David Benjaminef14b2d2015-11-11 14:01:27 -0800695 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400696 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400697 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400698 return false;
699 }
700 ERR_clear_error();
701 return true;
702}
703
David Benjamin10e664b2016-06-20 22:20:47 -0400704static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400705 const SSL_METHOD *(*method)(void)) {
706 ScopedSSL_CTX ctx(SSL_CTX_new(method()));
707 if (!ctx) {
708 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500709 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400710 if (ctx->min_version != min_version || ctx->max_version != max_version) {
711 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
712 ctx->min_version, ctx->max_version, min_version, max_version);
713 return false;
714 }
715 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500716}
717
David Benjamin1d77e562015-03-22 17:22:08 -0400718static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500719 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
720 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400721 return false;
David Benjamin65226252015-02-05 16:49:47 -0500722 }
Adam Langley10f97f32016-07-12 08:09:33 -0700723 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400724 if (!rfc_name) {
725 return false;
726 }
David Benjamin67be0482015-04-20 16:19:00 -0400727 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400728 return true;
David Benjamin65226252015-02-05 16:49:47 -0500729}
730
731typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500732 int id;
David Benjamin65226252015-02-05 16:49:47 -0500733 const char *rfc_name;
734} CIPHER_RFC_NAME_TEST;
735
736static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500737 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
738 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
739 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500740 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
741 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
742 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500743 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
744 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
745 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
746 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
747 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
748 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
749 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
750 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
751 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
752 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
753 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Adam Langley85bc5602015-06-09 09:54:04 -0700754 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
755 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500756 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
757 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400758 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000759 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500760 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000761 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500762 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500763};
764
David Benjamin1d77e562015-03-22 17:22:08 -0400765static bool TestCipherGetRFCName(void) {
766 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400767 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500768 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400769 std::string rfc_name;
770 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
771 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
772 return false;
David Benjamin65226252015-02-05 16:49:47 -0500773 }
David Benjamin1d77e562015-03-22 17:22:08 -0400774 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500775 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400776 rfc_name.c_str(), test->rfc_name);
777 return false;
David Benjamin65226252015-02-05 16:49:47 -0500778 }
David Benjamin65226252015-02-05 16:49:47 -0500779 }
David Benjamin1d77e562015-03-22 17:22:08 -0400780 return true;
David Benjamin65226252015-02-05 16:49:47 -0500781}
782
David Benjamin422fe082015-07-21 22:03:43 -0400783// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
784// replaced for one of length |ticket_len| or nullptr on failure.
785static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
786 std::vector<uint8_t> der;
787 if (!DecodeBase64(&der, kOpenSSLSession)) {
788 return nullptr;
789 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800790 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400791 if (!session) {
792 return nullptr;
793 }
794
795 // Swap out the ticket for a garbage one.
796 OPENSSL_free(session->tlsext_tick);
797 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
798 if (session->tlsext_tick == nullptr) {
799 return nullptr;
800 }
801 memset(session->tlsext_tick, 'a', ticket_len);
802 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400803
804 // Fix up the timeout.
805 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400806 return session;
807}
808
David Benjaminafc64de2016-07-19 17:12:41 +0200809static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
810 ScopedBIO bio(BIO_new(BIO_s_mem()));
811 if (!bio) {
812 return false;
813 }
814 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400815 BIO_up_ref(bio.get());
816 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200817 int ret = SSL_connect(ssl);
818 if (ret > 0) {
819 // SSL_connect should fail without a BIO to write to.
820 return false;
821 }
822 ERR_clear_error();
823
824 const uint8_t *client_hello;
825 size_t client_hello_len;
826 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
827 return false;
828 }
829 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
830 return true;
831}
832
David Benjamin422fe082015-07-21 22:03:43 -0400833// GetClientHelloLen creates a client SSL connection with a ticket of length
834// |ticket_len| and records the ClientHello. It returns the length of the
835// ClientHello, not including the record header, on success and zero on error.
836static size_t GetClientHelloLen(size_t ticket_len) {
837 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
838 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
839 if (!ctx || !session) {
840 return 0;
841 }
842 ScopedSSL ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200843 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400844 return 0;
845 }
David Benjaminafc64de2016-07-19 17:12:41 +0200846 std::vector<uint8_t> client_hello;
847 if (!GetClientHello(ssl.get(), &client_hello) ||
848 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400849 return 0;
850 }
David Benjaminafc64de2016-07-19 17:12:41 +0200851 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400852}
853
854struct PaddingTest {
855 size_t input_len, padded_len;
856};
857
858static const PaddingTest kPaddingTests[] = {
859 // ClientHellos of length below 0x100 do not require padding.
860 {0xfe, 0xfe},
861 {0xff, 0xff},
862 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
863 {0x100, 0x200},
864 {0x123, 0x200},
865 {0x1fb, 0x200},
866 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
867 // padding extension takes a minimum of four bytes plus one required content
868 // byte. (To work around yet more server bugs, we avoid empty final
869 // extensions.)
870 {0x1fc, 0x201},
871 {0x1fd, 0x202},
872 {0x1fe, 0x203},
873 {0x1ff, 0x204},
874 // Finally, larger ClientHellos need no padding.
875 {0x200, 0x200},
876 {0x201, 0x201},
877};
878
879static bool TestPaddingExtension() {
880 // Sample a baseline length.
881 size_t base_len = GetClientHelloLen(1);
882 if (base_len == 0) {
883 return false;
884 }
885
886 for (const PaddingTest &test : kPaddingTests) {
887 if (base_len > test.input_len) {
888 fprintf(stderr, "Baseline ClientHello too long.\n");
889 return false;
890 }
891
892 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
893 if (padded_len != test.padded_len) {
894 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
895 static_cast<unsigned>(test.input_len),
896 static_cast<unsigned>(padded_len),
897 static_cast<unsigned>(test.padded_len));
898 return false;
899 }
900 }
901 return true;
902}
903
David Benjamin1d128f32015-09-08 17:41:40 -0400904// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
905// before configuring as a server.
906static bool TestClientCAList() {
907 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
908 if (!ctx) {
909 return false;
910 }
911 ScopedSSL ssl(SSL_new(ctx.get()));
912 if (!ssl) {
913 return false;
914 }
915
916 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
917 if (stack == nullptr) {
918 return false;
919 }
920 // |SSL_set_client_CA_list| takes ownership.
921 SSL_set_client_CA_list(ssl.get(), stack);
922
923 return SSL_get_client_CA_list(ssl.get()) == stack;
924}
925
David Benjamin0f653952015-10-18 14:28:01 -0400926static void AppendSession(SSL_SESSION *session, void *arg) {
927 std::vector<SSL_SESSION*> *out =
928 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
929 out->push_back(session);
930}
931
932// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
933// order.
934static bool ExpectCache(SSL_CTX *ctx,
935 const std::vector<SSL_SESSION*> &expected) {
936 // Check the linked list.
937 SSL_SESSION *ptr = ctx->session_cache_head;
938 for (SSL_SESSION *session : expected) {
939 if (ptr != session) {
940 return false;
941 }
942 // TODO(davidben): This is an absurd way to denote the end of the list.
943 if (ptr->next ==
944 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
945 ptr = nullptr;
946 } else {
947 ptr = ptr->next;
948 }
949 }
950 if (ptr != nullptr) {
951 return false;
952 }
953
954 // Check the hash table.
955 std::vector<SSL_SESSION*> actual, expected_copy;
956 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
957 expected_copy = expected;
958
959 std::sort(actual.begin(), actual.end());
960 std::sort(expected_copy.begin(), expected_copy.end());
961
962 return actual == expected_copy;
963}
964
965static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
966 ScopedSSL_SESSION ret(SSL_SESSION_new());
967 if (!ret) {
968 return nullptr;
969 }
970
971 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
972 memset(ret->session_id, 0, ret->session_id_length);
973 memcpy(ret->session_id, &number, sizeof(number));
974 return ret;
975}
976
David Benjamin0f653952015-10-18 14:28:01 -0400977// Test that the internal session cache behaves as expected.
978static bool TestInternalSessionCache() {
979 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
980 if (!ctx) {
981 return false;
982 }
983
984 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500985 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400986 for (int i = 0; i < 10; i++) {
987 ScopedSSL_SESSION session = CreateTestSession(i);
988 if (!session) {
989 return false;
990 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500991 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400992 }
993
994 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
995
996 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500997 for (const auto &session : sessions) {
998 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400999 return false;
1000 }
1001 }
1002
1003 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001004 std::vector<SSL_SESSION*> expected = {
1005 sessions[9].get(),
1006 sessions[8].get(),
1007 sessions[7].get(),
1008 sessions[6].get(),
1009 sessions[5].get(),
1010 };
David Benjamin0f653952015-10-18 14:28:01 -04001011 if (!ExpectCache(ctx.get(), expected)) {
1012 return false;
1013 }
1014
1015 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001016 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001017 !ExpectCache(ctx.get(), expected)) {
1018 return false;
1019 }
1020
1021 // Although collisions should be impossible (256-bit session IDs), the cache
1022 // must handle them gracefully.
1023 ScopedSSL_SESSION collision(CreateTestSession(7));
1024 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1025 return false;
1026 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001027 expected = {
1028 collision.get(),
1029 sessions[9].get(),
1030 sessions[8].get(),
1031 sessions[6].get(),
1032 sessions[5].get(),
1033 };
David Benjamin0f653952015-10-18 14:28:01 -04001034 if (!ExpectCache(ctx.get(), expected)) {
1035 return false;
1036 }
1037
1038 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001039 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001040 return false;
1041 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001042 expected = {
1043 collision.get(),
1044 sessions[9].get(),
1045 sessions[8].get(),
1046 sessions[5].get(),
1047 };
David Benjamin0f653952015-10-18 14:28:01 -04001048 if (!ExpectCache(ctx.get(), expected)) {
1049 return false;
1050 }
1051
1052 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001053 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1054 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001055 !ExpectCache(ctx.get(), expected)) {
1056 return false;
1057 }
1058
1059 return true;
1060}
1061
David Benjaminde942382016-02-11 12:02:01 -05001062static uint16_t EpochFromSequence(uint64_t seq) {
1063 return static_cast<uint16_t>(seq >> 48);
1064}
1065
1066static ScopedX509 GetTestCertificate() {
1067 static const char kCertPEM[] =
1068 "-----BEGIN CERTIFICATE-----\n"
1069 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1070 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1071 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1072 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1073 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1074 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1075 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1076 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1077 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1078 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1079 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1080 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1081 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1082 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001083 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001084 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1085}
1086
1087static ScopedEVP_PKEY GetTestKey() {
1088 static const char kKeyPEM[] =
1089 "-----BEGIN RSA PRIVATE KEY-----\n"
1090 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1091 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1092 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1093 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1094 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1095 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1096 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1097 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1098 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1099 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1100 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1101 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1102 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1103 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001104 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001105 return ScopedEVP_PKEY(
1106 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1107}
1108
David Benjamin0fc37ef2016-08-17 15:29:46 -04001109static ScopedX509 GetECDSATestCertificate() {
1110 static const char kCertPEM[] =
1111 "-----BEGIN CERTIFICATE-----\n"
1112 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1113 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1114 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1115 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1116 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1117 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1118 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1119 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1120 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1121 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1122 "-----END CERTIFICATE-----\n";
1123 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1124 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1125}
1126
1127static ScopedEVP_PKEY GetECDSATestKey() {
1128 static const char kKeyPEM[] =
1129 "-----BEGIN PRIVATE KEY-----\n"
1130 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1131 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1132 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1133 "-----END PRIVATE KEY-----\n";
1134 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1135 return ScopedEVP_PKEY(
1136 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1137}
1138
David Benjamin686bb192016-05-10 15:15:41 -04001139static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001140 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1141 SSL_SESSION *session) {
David Benjamin686bb192016-05-10 15:15:41 -04001142 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001143 if (!client || !server) {
1144 return false;
1145 }
1146 SSL_set_connect_state(client.get());
1147 SSL_set_accept_state(server.get());
1148
David Benjamina20e5352016-08-02 19:09:41 -04001149 SSL_set_session(client.get(), session);
1150
David Benjaminde942382016-02-11 12:02:01 -05001151 BIO *bio1, *bio2;
1152 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1153 return false;
1154 }
1155 // SSL_set_bio takes ownership.
1156 SSL_set_bio(client.get(), bio1, bio1);
1157 SSL_set_bio(server.get(), bio2, bio2);
1158
1159 // Drive both their handshakes to completion.
1160 for (;;) {
1161 int client_ret = SSL_do_handshake(client.get());
1162 int client_err = SSL_get_error(client.get(), client_ret);
1163 if (client_err != SSL_ERROR_NONE &&
1164 client_err != SSL_ERROR_WANT_READ &&
1165 client_err != SSL_ERROR_WANT_WRITE) {
1166 fprintf(stderr, "Client error: %d\n", client_err);
1167 return false;
1168 }
1169
1170 int server_ret = SSL_do_handshake(server.get());
1171 int server_err = SSL_get_error(server.get(), server_ret);
1172 if (server_err != SSL_ERROR_NONE &&
1173 server_err != SSL_ERROR_WANT_READ &&
1174 server_err != SSL_ERROR_WANT_WRITE) {
1175 fprintf(stderr, "Server error: %d\n", server_err);
1176 return false;
1177 }
1178
1179 if (client_ret == 1 && server_ret == 1) {
1180 break;
1181 }
1182 }
1183
David Benjamin686bb192016-05-10 15:15:41 -04001184 *out_client = std::move(client);
1185 *out_server = std::move(server);
1186 return true;
1187}
1188
1189static bool TestSequenceNumber(bool dtls) {
1190 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1191 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1192 if (!client_ctx || !server_ctx) {
1193 return false;
1194 }
1195
1196 ScopedX509 cert = GetTestCertificate();
1197 ScopedEVP_PKEY key = GetTestKey();
1198 if (!cert || !key ||
1199 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1200 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1201 return false;
1202 }
1203
1204 ScopedSSL client, server;
1205 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001206 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001207 return false;
1208 }
1209
David Benjaminde942382016-02-11 12:02:01 -05001210 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1211 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1212 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1213 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1214
1215 if (dtls) {
1216 // Both client and server must be at epoch 1.
1217 if (EpochFromSequence(client_read_seq) != 1 ||
1218 EpochFromSequence(client_write_seq) != 1 ||
1219 EpochFromSequence(server_read_seq) != 1 ||
1220 EpochFromSequence(server_write_seq) != 1) {
1221 fprintf(stderr, "Bad epochs.\n");
1222 return false;
1223 }
1224
1225 // The next record to be written should exceed the largest received.
1226 if (client_write_seq <= server_read_seq ||
1227 server_write_seq <= client_read_seq) {
1228 fprintf(stderr, "Inconsistent sequence numbers.\n");
1229 return false;
1230 }
1231 } else {
1232 // The next record to be written should equal the next to be received.
1233 if (client_write_seq != server_read_seq ||
1234 server_write_seq != client_write_seq) {
1235 fprintf(stderr, "Inconsistent sequence numbers.\n");
1236 return false;
1237 }
1238 }
1239
1240 // Send a record from client to server.
1241 uint8_t byte = 0;
1242 if (SSL_write(client.get(), &byte, 1) != 1 ||
1243 SSL_read(server.get(), &byte, 1) != 1) {
1244 fprintf(stderr, "Could not send byte.\n");
1245 return false;
1246 }
1247
1248 // The client write and server read sequence numbers should have incremented.
1249 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1250 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1251 fprintf(stderr, "Sequence numbers did not increment.\n");\
1252 return false;
1253 }
1254
1255 return true;
1256}
1257
David Benjamin686bb192016-05-10 15:15:41 -04001258static bool TestOneSidedShutdown() {
1259 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1260 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1261 if (!client_ctx || !server_ctx) {
1262 return false;
1263 }
1264
1265 ScopedX509 cert = GetTestCertificate();
1266 ScopedEVP_PKEY key = GetTestKey();
1267 if (!cert || !key ||
1268 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1269 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1270 return false;
1271 }
1272
1273 ScopedSSL client, server;
1274 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001275 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001276 return false;
1277 }
1278
1279 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1280 // one side has shut down.
1281 if (SSL_shutdown(client.get()) != 0) {
1282 fprintf(stderr, "Could not shutdown.\n");
1283 return false;
1284 }
1285
1286 // Reading from the server should consume the EOF.
1287 uint8_t byte;
1288 if (SSL_read(server.get(), &byte, 1) != 0 ||
1289 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1290 fprintf(stderr, "Connection was not shut down cleanly.\n");
1291 return false;
1292 }
1293
1294 // However, the server may continue to write data and then shut down the
1295 // connection.
1296 byte = 42;
1297 if (SSL_write(server.get(), &byte, 1) != 1 ||
1298 SSL_read(client.get(), &byte, 1) != 1 ||
1299 byte != 42) {
1300 fprintf(stderr, "Could not send byte.\n");
1301 return false;
1302 }
1303
1304 // The server may then shutdown the connection.
1305 if (SSL_shutdown(server.get()) != 1 ||
1306 SSL_shutdown(client.get()) != 1) {
1307 fprintf(stderr, "Could not complete shutdown.\n");
1308 return false;
1309 }
1310
1311 return true;
1312}
Steven Valdez87eab492016-06-27 16:34:59 -04001313static bool TestSessionDuplication() {
1314 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1315 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1316 if (!client_ctx || !server_ctx) {
1317 return false;
1318 }
1319
1320 ScopedX509 cert = GetTestCertificate();
1321 ScopedEVP_PKEY key = GetTestKey();
1322 if (!cert || !key ||
1323 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1324 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1325 return false;
1326 }
1327
1328 ScopedSSL client, server;
1329 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001330 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001331 return false;
1332 }
1333
1334 SSL_SESSION *session0 = SSL_get_session(client.get());
Steven Valdez4aa154e2016-07-29 14:32:55 -04001335 ScopedSSL_SESSION session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001336 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001337 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001338 }
David Benjamin4501bd52016-08-01 13:39:41 -04001339
Steven Valdez87eab492016-06-27 16:34:59 -04001340 uint8_t *s0_bytes, *s1_bytes;
1341 size_t s0_len, s1_len;
1342
1343 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1344 return false;
1345 }
1346 ScopedOpenSSLBytes free_s0(s0_bytes);
1347
1348 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1349 return false;
1350 }
1351 ScopedOpenSSLBytes free_s1(s1_bytes);
1352
1353 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1354}
David Benjamin686bb192016-05-10 15:15:41 -04001355
David Benjamin5c0fb882016-06-14 14:03:51 -04001356static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1357 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1358 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1359 SSL_get_wfd(ssl), rfd, wfd);
1360 return false;
1361 }
1362
1363 // The wrapper BIOs are always equal when fds are equal, even if set
1364 // individually.
1365 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1366 fprintf(stderr, "rbio and wbio did not match.\n");
1367 return false;
1368 }
1369
1370 return true;
1371}
1372
1373static bool TestSetFD() {
1374 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1375 if (!ctx) {
1376 return false;
1377 }
1378
1379 // Test setting different read and write FDs.
1380 ScopedSSL ssl(SSL_new(ctx.get()));
1381 if (!ssl ||
1382 !SSL_set_rfd(ssl.get(), 1) ||
1383 !SSL_set_wfd(ssl.get(), 2) ||
1384 !ExpectFDs(ssl.get(), 1, 2)) {
1385 return false;
1386 }
1387
1388 // Test setting the same FD.
1389 ssl.reset(SSL_new(ctx.get()));
1390 if (!ssl ||
1391 !SSL_set_fd(ssl.get(), 1) ||
1392 !ExpectFDs(ssl.get(), 1, 1)) {
1393 return false;
1394 }
1395
1396 // Test setting the same FD one side at a time.
1397 ssl.reset(SSL_new(ctx.get()));
1398 if (!ssl ||
1399 !SSL_set_rfd(ssl.get(), 1) ||
1400 !SSL_set_wfd(ssl.get(), 1) ||
1401 !ExpectFDs(ssl.get(), 1, 1)) {
1402 return false;
1403 }
1404
1405 // Test setting the same FD in the other order.
1406 ssl.reset(SSL_new(ctx.get()));
1407 if (!ssl ||
1408 !SSL_set_wfd(ssl.get(), 1) ||
1409 !SSL_set_rfd(ssl.get(), 1) ||
1410 !ExpectFDs(ssl.get(), 1, 1)) {
1411 return false;
1412 }
1413
David Benjamin5c0fb882016-06-14 14:03:51 -04001414 // Test changing the read FD partway through.
1415 ssl.reset(SSL_new(ctx.get()));
1416 if (!ssl ||
1417 !SSL_set_fd(ssl.get(), 1) ||
1418 !SSL_set_rfd(ssl.get(), 2) ||
1419 !ExpectFDs(ssl.get(), 2, 1)) {
1420 return false;
1421 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001422
1423 // Test changing the write FD partway through.
1424 ssl.reset(SSL_new(ctx.get()));
1425 if (!ssl ||
1426 !SSL_set_fd(ssl.get(), 1) ||
1427 !SSL_set_wfd(ssl.get(), 2) ||
1428 !ExpectFDs(ssl.get(), 1, 2)) {
1429 return false;
1430 }
1431
1432 // Test a no-op change to the read FD partway through.
1433 ssl.reset(SSL_new(ctx.get()));
1434 if (!ssl ||
1435 !SSL_set_fd(ssl.get(), 1) ||
1436 !SSL_set_rfd(ssl.get(), 1) ||
1437 !ExpectFDs(ssl.get(), 1, 1)) {
1438 return false;
1439 }
1440
1441 // Test a no-op change to the write FD partway through.
1442 ssl.reset(SSL_new(ctx.get()));
1443 if (!ssl ||
1444 !SSL_set_fd(ssl.get(), 1) ||
1445 !SSL_set_wfd(ssl.get(), 1) ||
1446 !ExpectFDs(ssl.get(), 1, 1)) {
1447 return false;
1448 }
1449
1450 // ASan builds will implicitly test that the internal |BIO| reference-counting
1451 // is correct.
1452
1453 return true;
1454}
1455
David Benjamin4501bd52016-08-01 13:39:41 -04001456static bool TestSetBIO() {
1457 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1458 if (!ctx) {
1459 return false;
1460 }
1461
1462 ScopedSSL ssl(SSL_new(ctx.get()));
1463 ScopedBIO bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
1464 bio3(BIO_new(BIO_s_mem()));
1465 if (!ssl || !bio1 || !bio2 || !bio3) {
1466 return false;
1467 }
1468
1469 // SSL_set_bio takes one reference when the parameters are the same.
1470 BIO_up_ref(bio1.get());
1471 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1472
1473 // Repeating the call does nothing.
1474 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1475
1476 // It takes one reference each when the parameters are different.
1477 BIO_up_ref(bio2.get());
1478 BIO_up_ref(bio3.get());
1479 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1480
1481 // Repeating the call does nothing.
1482 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1483
1484 // It takes one reference when changing only wbio.
1485 BIO_up_ref(bio1.get());
1486 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1487
1488 // It takes one reference when changing only rbio and the two are different.
1489 BIO_up_ref(bio3.get());
1490 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1491
1492 // If setting wbio to rbio, it takes no additional references.
1493 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1494
1495 // From there, wbio may be switched to something else.
1496 BIO_up_ref(bio1.get());
1497 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1498
1499 // If setting rbio to wbio, it takes no additional references.
1500 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1501
1502 // From there, rbio may be switched to something else, but, for historical
1503 // reasons, it takes a reference to both parameters.
1504 BIO_up_ref(bio1.get());
1505 BIO_up_ref(bio2.get());
1506 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1507
1508 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1509 // is correct.
1510 return true;
1511}
1512
David Benjamin25490f22016-07-14 00:22:54 -04001513static uint16_t kVersions[] = {
1514 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1515};
1516
1517static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1518
David Benjaminadd5e522016-07-14 00:33:24 -04001519static bool TestGetPeerCertificate() {
1520 ScopedX509 cert = GetTestCertificate();
1521 ScopedEVP_PKEY key = GetTestKey();
1522 if (!cert || !key) {
1523 return false;
1524 }
1525
1526 for (uint16_t version : kVersions) {
1527 // Configure both client and server to accept any certificate.
1528 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1529 if (!ctx ||
1530 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1531 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1532 return false;
1533 }
1534 SSL_CTX_set_min_version(ctx.get(), version);
1535 SSL_CTX_set_max_version(ctx.get(), version);
1536 SSL_CTX_set_verify(
1537 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1538 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1539
1540 ScopedSSL client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001541 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1542 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001543 return false;
1544 }
1545
1546 // Client and server should both see the leaf certificate.
1547 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1548 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1549 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1550 return false;
1551 }
1552
1553 peer.reset(SSL_get_peer_certificate(client.get()));
1554 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1555 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1556 return false;
1557 }
1558
1559 // However, for historical reasons, the chain includes the leaf on the
1560 // client, but does not on the server.
1561 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1562 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1563 return false;
1564 }
1565
1566 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1567 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1568 return false;
1569 }
1570 }
1571
1572 return true;
1573}
1574
David Benjamin25490f22016-07-14 00:22:54 -04001575static bool TestRetainOnlySHA256OfCerts() {
1576 ScopedX509 cert = GetTestCertificate();
1577 ScopedEVP_PKEY key = GetTestKey();
1578 if (!cert || !key) {
1579 return false;
1580 }
1581
1582 uint8_t *cert_der = NULL;
1583 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1584 if (cert_der_len < 0) {
1585 return false;
1586 }
1587 ScopedOpenSSLBytes free_cert_der(cert_der);
1588
1589 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1590 SHA256(cert_der, cert_der_len, cert_sha256);
1591
1592 for (uint16_t version : kVersions) {
1593 // Configure both client and server to accept any certificate, but the
1594 // server must retain only the SHA-256 of the peer.
1595 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1596 if (!ctx ||
1597 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1598 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1599 return false;
1600 }
1601 SSL_CTX_set_min_version(ctx.get(), version);
1602 SSL_CTX_set_max_version(ctx.get(), version);
1603 SSL_CTX_set_verify(
1604 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1605 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1606 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1607
1608 ScopedSSL client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001609 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1610 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001611 return false;
1612 }
1613
1614 // The peer certificate has been dropped.
1615 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1616 if (peer) {
1617 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1618 return false;
1619 }
1620
1621 SSL_SESSION *session = SSL_get_session(server.get());
1622 if (!session->peer_sha256_valid) {
1623 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1624 return false;
1625 }
1626
1627 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1628 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1629 return false;
1630 }
1631 }
1632
1633 return true;
1634}
1635
David Benjaminafc64de2016-07-19 17:12:41 +02001636static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1637 size_t expected_len) {
1638 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1639 if (!ctx) {
1640 return false;
1641 }
1642 SSL_CTX_set_max_version(ctx.get(), version);
1643 // Our default cipher list varies by CPU capabilities, so manually place the
1644 // ChaCha20 ciphers in front.
1645 if (!SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
1646 return false;
1647 }
1648 ScopedSSL ssl(SSL_new(ctx.get()));
1649 if (!ssl) {
1650 return false;
1651 }
1652 std::vector<uint8_t> client_hello;
1653 if (!GetClientHello(ssl.get(), &client_hello)) {
1654 return false;
1655 }
1656
1657 // Zero the client_random.
1658 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1659 1 + 3 + // handshake message header
1660 2; // client_version
1661 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1662 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1663 return false;
1664 }
1665 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1666
1667 if (client_hello.size() != expected_len ||
1668 memcmp(client_hello.data(), expected, expected_len) != 0) {
1669 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1670 fprintf(stderr, "Got:\n\t");
1671 for (size_t i = 0; i < client_hello.size(); i++) {
1672 fprintf(stderr, "0x%02x, ", client_hello[i]);
1673 }
1674 fprintf(stderr, "\nWanted:\n\t");
1675 for (size_t i = 0; i < expected_len; i++) {
1676 fprintf(stderr, "0x%02x, ", expected[i]);
1677 }
1678 fprintf(stderr, "\n");
1679 return false;
1680 }
1681
1682 return true;
1683}
1684
1685// Tests that our ClientHellos do not change unexpectedly.
1686static bool TestClientHello() {
1687 static const uint8_t kSSL3ClientHello[] = {
1688 0x16, 0x03, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x43, 0x03, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1692 0x00, 0x1c, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0,
1693 0x14, 0x00, 0x39, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35,
1694 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x00, 0xff, 0x01, 0x00,
1695 };
1696 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1697 sizeof(kSSL3ClientHello))) {
1698 return false;
1699 }
1700
1701 static const uint8_t kTLS1ClientHello[] = {
1702 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x01, 0x00,
1703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
1706 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
1707 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
1708 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1709 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1710 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1711 };
1712 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1713 sizeof(kTLS1ClientHello))) {
1714 return false;
1715 }
1716
1717 static const uint8_t kTLS11ClientHello[] = {
1718 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x02, 0x00,
1719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
1722 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
1723 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
1724 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1725 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1726 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1727 };
1728 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1729 sizeof(kTLS11ClientHello))) {
1730 return false;
1731 }
1732
1733 static const uint8_t kTLS12ClientHello[] = {
1734 0x16, 0x03, 0x01, 0x00, 0xa4, 0x01, 0x00, 0x00, 0xa0, 0x03, 0x03, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcc, 0xa9,
1738 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1739 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1740 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1741 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x9c,
1742 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a,
1743 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x35, 0xff, 0x01, 0x00, 0x01,
1744 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1745 0x12, 0x00, 0x10, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04,
1746 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01,
1747 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1748 0x18,
1749 };
1750 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1751 sizeof(kTLS12ClientHello))) {
1752 return false;
1753 }
1754
1755 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1756 // implementation has settled enough that it won't change.
1757
1758 return true;
1759}
1760
David Benjamina20e5352016-08-02 19:09:41 -04001761static ScopedSSL_SESSION g_last_session;
1762
1763static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1764 // Save the most recent session.
1765 g_last_session.reset(session);
1766 return 1;
1767}
1768
1769static ScopedSSL_SESSION CreateClientSession(SSL_CTX *client_ctx,
1770 SSL_CTX *server_ctx) {
1771 g_last_session = nullptr;
1772 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1773
1774 // Connect client and server to get a session.
1775 ScopedSSL client, server;
1776 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1777 nullptr /* no session */)) {
1778 fprintf(stderr, "Failed to connect client and server.\n");
1779 return nullptr;
1780 }
1781
1782 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1783 SSL_read(client.get(), nullptr, 0);
1784
1785 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1786
1787 if (!g_last_session) {
1788 fprintf(stderr, "Client did not receive a session.\n");
1789 return nullptr;
1790 }
1791 return std::move(g_last_session);
1792}
1793
1794static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1795 SSL_SESSION *session,
1796 bool reused) {
1797 ScopedSSL client, server;
1798 if (!ConnectClientAndServer(&client, &server, client_ctx,
1799 server_ctx, session)) {
1800 fprintf(stderr, "Failed to connect client and server.\n");
1801 return false;
1802 }
1803
1804 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1805 fprintf(stderr, "Client and server were inconsistent.\n");
1806 return false;
1807 }
1808
1809 bool was_reused = !!SSL_session_reused(client.get());
1810 if (was_reused != reused) {
1811 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1812 was_reused ? "" : " not");
1813 return false;
1814 }
1815
1816 return true;
1817}
1818
1819static bool TestSessionIDContext() {
1820 ScopedX509 cert = GetTestCertificate();
1821 ScopedEVP_PKEY key = GetTestKey();
1822 if (!cert || !key) {
1823 return false;
1824 }
1825
1826 static const uint8_t kContext1[] = {1};
1827 static const uint8_t kContext2[] = {2};
1828
1829 for (uint16_t version : kVersions) {
David Benjamina20e5352016-08-02 19:09:41 -04001830 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1831 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1832 if (!server_ctx || !client_ctx ||
1833 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1834 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1835 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
1836 sizeof(kContext1))) {
1837 return false;
1838 }
1839
1840 SSL_CTX_set_min_version(client_ctx.get(), version);
1841 SSL_CTX_set_max_version(client_ctx.get(), version);
1842 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1843
1844 SSL_CTX_set_min_version(server_ctx.get(), version);
1845 SSL_CTX_set_max_version(server_ctx.get(), version);
1846 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1847
1848 ScopedSSL_SESSION session =
1849 CreateClientSession(client_ctx.get(), server_ctx.get());
1850 if (!session) {
1851 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1852 return false;
1853 }
1854
1855 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1856 true /* expect session reused */)) {
1857 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1858 return false;
1859 }
1860
1861 // Change the session ID context.
1862 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1863 sizeof(kContext2))) {
1864 return false;
1865 }
1866
1867 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1868 false /* expect session not reused */)) {
1869 fprintf(stderr,
1870 "Error connection with different context (version = %04x).\n",
1871 version);
1872 return false;
1873 }
1874 }
1875
1876 return true;
1877}
1878
David Benjamin721e8b72016-08-03 13:13:17 -04001879static timeval g_current_time;
1880
1881static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1882 *out_clock = g_current_time;
1883}
1884
1885static bool TestSessionTimeout() {
1886 ScopedX509 cert = GetTestCertificate();
1887 ScopedEVP_PKEY key = GetTestKey();
1888 if (!cert || !key) {
1889 return false;
1890 }
1891
1892 for (uint16_t version : kVersions) {
David Benjamin721e8b72016-08-03 13:13:17 -04001893 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1894 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1895 if (!server_ctx || !client_ctx ||
1896 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1897 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1898 return false;
1899 }
1900
1901 SSL_CTX_set_min_version(client_ctx.get(), version);
1902 SSL_CTX_set_max_version(client_ctx.get(), version);
1903 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1904
1905 SSL_CTX_set_min_version(server_ctx.get(), version);
1906 SSL_CTX_set_max_version(server_ctx.get(), version);
1907 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1908 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1909
1910 ScopedSSL_SESSION session =
1911 CreateClientSession(client_ctx.get(), server_ctx.get());
1912 if (!session) {
1913 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1914 return false;
1915 }
1916
1917 // Advance the clock just behind the timeout.
1918 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
1919
1920 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1921 true /* expect session reused */)) {
1922 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1923 return false;
1924 }
1925
1926 // Advance the clock one more second.
1927 g_current_time.tv_sec++;
1928
1929 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1930 false /* expect session not reused */)) {
1931 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1932 return false;
1933 }
1934 }
1935
1936 return true;
1937}
1938
David Benjamin0fc37ef2016-08-17 15:29:46 -04001939static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
1940 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
1941 SSL_set_SSL_CTX(ssl, ctx);
1942 return SSL_TLSEXT_ERR_OK;
1943}
1944
1945static bool TestSNICallback() {
1946 ScopedX509 cert = GetTestCertificate();
1947 ScopedEVP_PKEY key = GetTestKey();
1948 ScopedX509 cert2 = GetECDSATestCertificate();
1949 ScopedEVP_PKEY key2 = GetECDSATestKey();
1950 if (!cert || !key || !cert2 || !key2) {
1951 return false;
1952 }
1953
1954 // At each version, test that switching the |SSL_CTX| at the SNI callback
1955 // behaves correctly.
1956 for (uint16_t version : kVersions) {
1957 if (version == SSL3_VERSION) {
1958 continue;
1959 }
1960
1961 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
1962
1963 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1964 ScopedSSL_CTX server_ctx2(SSL_CTX_new(TLS_method()));
1965 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1966 if (!server_ctx || !server_ctx2 || !client_ctx ||
1967 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1968 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1969 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
1970 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
1971 // Historically signing preferences would be lost in some cases with the
1972 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
1973 // this doesn't happen when |version| is TLS 1.2, configure the private
1974 // key to only sign SHA-256.
1975 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
1976 &kECDSAWithSHA256, 1)) {
1977 return false;
1978 }
1979
1980 SSL_CTX_set_min_version(client_ctx.get(), version);
1981 SSL_CTX_set_max_version(client_ctx.get(), version);
1982 SSL_CTX_set_min_version(server_ctx.get(), version);
1983 SSL_CTX_set_max_version(server_ctx.get(), version);
1984 SSL_CTX_set_min_version(server_ctx2.get(), version);
1985 SSL_CTX_set_max_version(server_ctx2.get(), version);
1986
1987 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
1988 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
1989
1990 ScopedSSL client, server;
1991 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1992 server_ctx.get(), nullptr)) {
1993 fprintf(stderr, "Handshake failed at version %04x.\n", version);
1994 return false;
1995 }
1996
1997 // The client should have received |cert2|.
1998 ScopedX509 peer(SSL_get_peer_certificate(client.get()));
1999 if (!peer ||
2000 X509_cmp(peer.get(), cert2.get()) != 0) {
2001 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2002 version);
2003 return false;
2004 }
2005 }
2006
2007 return true;
2008}
2009
David Benjamin1d128f32015-09-08 17:41:40 -04002010int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002011 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002012
Adam Langley10f97f32016-07-12 08:09:33 -07002013 if (!TestCipherRules() ||
2014 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2015 !TestSSL_SESSIONEncoding(kCustomSession) ||
2016 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2017 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2018 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2019 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002020 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002021 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2022 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2023 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2024 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2025 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2026 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2027 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2028 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2029 !TestCipherGetRFCName() ||
2030 !TestPaddingExtension() ||
2031 !TestClientCAList() ||
2032 !TestInternalSessionCache() ||
2033 !TestSequenceNumber(false /* TLS */) ||
2034 !TestSequenceNumber(true /* DTLS */) ||
2035 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002036 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002037 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002038 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002039 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002040 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002041 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002042 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002043 !TestSessionTimeout() ||
2044 !TestSNICallback()) {
Brian Smith83a82982015-04-09 16:21:10 -10002045 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002046 return 1;
2047 }
2048
David Benjamin2e521212014-07-16 14:37:51 -04002049 printf("PASS\n");
2050 return 0;
2051}