blob: be3b8b7ccf6ea7050174d37ad21ee0d1304b2f2a [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 Benjaminbb0a17c2014-09-20 15:35:39 -040029#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050030#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040031
Adam Langleyd2b5af52016-07-12 08:03:59 -070032#include "test/scoped_types.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020033#include "../crypto/test/test_util.h"
34
David Benjamin1d77e562015-03-22 17:22:08 -040035
36struct ExpectedCipher {
37 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040038 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040039};
David Benjaminbb0a17c2014-09-20 15:35:39 -040040
David Benjamin1d77e562015-03-22 17:22:08 -040041struct CipherTest {
42 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040043 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050044 // The list of expected ciphers, in order.
45 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040046};
David Benjaminbb0a17c2014-09-20 15:35:39 -040047
David Benjaminfb974e62015-12-16 19:34:22 -050048static const CipherTest kCipherTests[] = {
49 // Selecting individual ciphers should work.
50 {
51 "ECDHE-ECDSA-CHACHA20-POLY1305:"
52 "ECDHE-RSA-CHACHA20-POLY1305:"
53 "ECDHE-ECDSA-AES128-GCM-SHA256:"
54 "ECDHE-RSA-AES128-GCM-SHA256",
55 {
56 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
57 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
58 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
59 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
60 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
61 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
62 },
63 },
64 // + reorders selected ciphers to the end, keeping their relative order.
65 {
66 "ECDHE-ECDSA-CHACHA20-POLY1305:"
67 "ECDHE-RSA-CHACHA20-POLY1305:"
68 "ECDHE-ECDSA-AES128-GCM-SHA256:"
69 "ECDHE-RSA-AES128-GCM-SHA256:"
70 "+aRSA",
71 {
72 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
73 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
74 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
75 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
76 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
77 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
78 },
79 },
80 // ! banishes ciphers from future selections.
81 {
82 "!aRSA:"
83 "ECDHE-ECDSA-CHACHA20-POLY1305:"
84 "ECDHE-RSA-CHACHA20-POLY1305:"
85 "ECDHE-ECDSA-AES128-GCM-SHA256:"
86 "ECDHE-RSA-AES128-GCM-SHA256",
87 {
88 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
89 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
90 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
91 },
92 },
93 // Multiple masks can be ANDed in a single rule.
94 {
95 "kRSA+AESGCM+AES128",
96 {
97 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
98 },
99 },
100 // - removes selected ciphers, but preserves their order for future
101 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
102 // ECDHE_RSA.
103 {
104 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
105 "AESGCM+AES128+aRSA",
106 {
107 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
108 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
109 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
110 },
111 },
112 // Unknown selectors are no-ops.
113 {
114 "ECDHE-ECDSA-CHACHA20-POLY1305:"
115 "ECDHE-RSA-CHACHA20-POLY1305:"
116 "ECDHE-ECDSA-AES128-GCM-SHA256:"
117 "ECDHE-RSA-AES128-GCM-SHA256:"
118 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
119 {
120 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
121 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
122 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
123 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
124 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
125 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
126 },
127 },
128 // Square brackets specify equi-preference groups.
129 {
130 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
131 "[ECDHE-RSA-CHACHA20-POLY1305]:"
132 "ECDHE-RSA-AES128-GCM-SHA256",
133 {
134 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
135 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
136 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
137 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
138 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
139 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
140 },
141 },
142 // @STRENGTH performs a stable strength-sort of the selected ciphers and
143 // only the selected ciphers.
144 {
145 // To simplify things, banish all but {ECDHE_RSA,RSA} x
146 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
147 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
148 // Order some ciphers backwards by strength.
149 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
150 // Select ECDHE ones and sort them by strength. Ties should resolve
151 // based on the order above.
152 "kECDHE:@STRENGTH:-ALL:"
153 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
154 // by strength. Then RSA, backwards by strength.
155 "aRSA",
156 {
157 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
158 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
159 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
160 {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
161 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
162 {SSL3_CK_RSA_RC4_128_SHA, 0},
163 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
164 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
165 },
166 },
167 // Exact ciphers may not be used in multi-part rules; they are treated
168 // as unknown aliases.
169 {
170 "ECDHE-ECDSA-AES128-GCM-SHA256:"
171 "ECDHE-RSA-AES128-GCM-SHA256:"
172 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
173 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
174 {
175 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
176 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
177 },
178 },
179 // SSLv3 matches everything that existed before TLS 1.2.
180 {
181 "AES128-SHA:AES128-SHA256:!SSLv3",
182 {
183 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
184 },
185 },
186 // TLSv1.2 matches everything added in TLS 1.2.
187 {
188 "AES128-SHA:AES128-SHA256:!TLSv1.2",
189 {
190 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
191 },
192 },
193 // The two directives have no intersection.
194 {
195 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
196 {
197 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
198 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
199 },
200 },
201 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
202 // name and not an alias. It may not be used in a multipart rule. (That the
203 // shared name works is covered by the standard tests.)
204 {
205 "ECDHE-ECDSA-CHACHA20-POLY1305:"
206 "ECDHE-RSA-CHACHA20-POLY1305:"
207 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
208 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
209 {
210 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
211 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
212 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
213 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
214 },
215 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400216};
217
218static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400219 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400220 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
221 "RSA]",
222 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400223 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400224 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400225 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400226 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400227 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400228 "",
229 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400230 // COMPLEMENTOFDEFAULT is empty.
231 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400232 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400233 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400234 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400235 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
237 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
238 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400239};
240
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700241static const char *kMustNotIncludeNull[] = {
242 "ALL",
243 "DEFAULT",
244 "ALL:!eNULL",
245 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500246 "MEDIUM",
247 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700248 "FIPS",
249 "SHA",
250 "SHA1",
251 "RSA",
252 "SSLv3",
253 "TLSv1",
254 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700255};
256
Matt Braithwaite053931e2016-05-25 12:06:05 -0700257static const char *kMustNotIncludeCECPQ1[] = {
258 "ALL",
259 "DEFAULT",
260 "MEDIUM",
261 "HIGH",
262 "FIPS",
263 "SHA",
264 "SHA1",
265 "SHA256",
266 "SHA384",
267 "RSA",
268 "SSLv3",
269 "TLSv1",
270 "TLSv1.2",
271 "aRSA",
272 "RSA",
273 "aECDSA",
274 "ECDSA",
275 "AES",
276 "AES128",
277 "AES256",
278 "AESGCM",
279 "CHACHA20",
280};
281
David Benjamin1d77e562015-03-22 17:22:08 -0400282static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
283 bool in_group = false;
284 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400285 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
286 if (!in_group && list->in_group_flags[i]) {
287 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400288 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400289 }
290 fprintf(stderr, "\t");
291 if (in_group) {
292 fprintf(stderr, " ");
293 }
294 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
295 if (in_group && !list->in_group_flags[i]) {
296 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400297 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400298 }
299 }
300}
301
David Benjaminfb974e62015-12-16 19:34:22 -0500302static bool TestCipherRule(const CipherTest &t) {
David Benjamin1d77e562015-03-22 17:22:08 -0400303 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
304 if (!ctx) {
305 return false;
David Benjamin65226252015-02-05 16:49:47 -0500306 }
307
David Benjaminfb974e62015-12-16 19:34:22 -0500308 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
309 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400310 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400311 }
312
David Benjamin1d77e562015-03-22 17:22:08 -0400313 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500314 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
315 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
316 PrintCipherPreferenceList(ctx->cipher_list);
317 return false;
318 }
319
320 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400321 const SSL_CIPHER *cipher =
322 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500323 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
324 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
325 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400326 PrintCipherPreferenceList(ctx->cipher_list);
327 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400328 }
329 }
330
David Benjamin1d77e562015-03-22 17:22:08 -0400331 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400332}
333
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700334static bool TestRuleDoesNotIncludeNull(const char *rule) {
335 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
336 if (!ctx) {
337 return false;
338 }
339 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
340 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
341 return false;
342 }
343 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
344 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
345 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
346 return false;
347 }
348 }
349 return true;
350}
351
Matt Braithwaite053931e2016-05-25 12:06:05 -0700352static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
353 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
354 if (!ctx) {
355 return false;
356 }
357 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
358 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
359 return false;
360 }
361 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
362 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
363 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
364 return false;
365 }
366 }
367 return true;
368}
369
David Benjamin1d77e562015-03-22 17:22:08 -0400370static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500371 for (const CipherTest &test : kCipherTests) {
372 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400373 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400374 }
375 }
376
David Benjaminfb974e62015-12-16 19:34:22 -0500377 for (const char *rule : kBadRules) {
David Benjamin1d77e562015-03-22 17:22:08 -0400378 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
379 if (!ctx) {
380 return false;
David Benjamin65226252015-02-05 16:49:47 -0500381 }
David Benjaminfb974e62015-12-16 19:34:22 -0500382 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
383 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400384 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400385 }
386 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400387 }
388
David Benjaminfb974e62015-12-16 19:34:22 -0500389 for (const char *rule : kMustNotIncludeNull) {
390 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700391 return false;
392 }
393 }
394
Matt Braithwaite053931e2016-05-25 12:06:05 -0700395 for (const char *rule : kMustNotIncludeCECPQ1) {
396 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
397 return false;
398 }
399 }
400
David Benjamin1d77e562015-03-22 17:22:08 -0400401 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400402}
David Benjamin2e521212014-07-16 14:37:51 -0400403
Adam Langley10f97f32016-07-12 08:09:33 -0700404// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
405// s_client -sess_out.
406static const char kOpenSSLSession[] =
407 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
408 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
409 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
410 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
411 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
412 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
413 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
414 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
415 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
416 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
417 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
418 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
419 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
420 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
421 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
422 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
423 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
424 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
425 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
426 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
427 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
428 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
429 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
430 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
431 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
432 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
433 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
434 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
435 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
436 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
437 "i4gv7Y5oliyn";
438
439// kCustomSession is a custom serialized SSL_SESSION generated by
440// filling in missing fields from |kOpenSSLSession|. This includes
441// providing |peer_sha256|, so |peer| is not serialized.
442static const char kCustomSession[] =
443 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
444 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
445 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
446 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
447 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
448 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
449 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
450 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
451
452// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
453static const char kBoringSSLSession[] =
454 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
455 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
456 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
457 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
458 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
459 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
460 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
461 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
462 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
463 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
464 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
465 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
466 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
467 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
468 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
469 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
470 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
471 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
472 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
473 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
474 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
475 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
476 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
477 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
478 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
479 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
480 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
481 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
482 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
483 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
484 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
485 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
486 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
487 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
488 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
489 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
490 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
491 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
492 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
493 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
494 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
495 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
496 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
497 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
498 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
499 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
500 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
501 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
502 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
503 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
504 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
505 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
506 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
507 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
508 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
509 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
510 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
511 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
512 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
513 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
514 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
515 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
516 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
517 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
518 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
519 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
520 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
521 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
522 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
523 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
524 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
525 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
526 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
527 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
528 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
529 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
530 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
531 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
532 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
533 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
534 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
535 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
536 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
537 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
538 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
539 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
540 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
541 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
542 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
543 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
544 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
545 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
546 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
547 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
548 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
549
550// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
551// the final (optional) element of |kCustomSession| with tag number 30.
552static const char kBadSessionExtraField[] =
553 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
554 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
555 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
556 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
557 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
558 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
559 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
560 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
561
562// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
563// the version of |kCustomSession| with 2.
564static const char kBadSessionVersion[] =
565 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
566 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
567 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
568 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
569 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
570 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
571 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
572 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
573
574// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
575// appended.
576static const char kBadSessionTrailingData[] =
577 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
578 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
579 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
580 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
581 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
582 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
583 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
584 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
585
David Benjamin1d77e562015-03-22 17:22:08 -0400586static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400587 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400588 if (!EVP_DecodedLength(&len, strlen(in))) {
589 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400590 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400591 }
592
David Benjamin1d77e562015-03-22 17:22:08 -0400593 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800594 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400595 strlen(in))) {
596 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400597 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400598 }
David Benjamin1d77e562015-03-22 17:22:08 -0400599 out->resize(len);
600 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400601}
602
David Benjamin1d77e562015-03-22 17:22:08 -0400603static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400604 const uint8_t *cptr;
605 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400606
David Benjamin1d77e562015-03-22 17:22:08 -0400607 // Decode the input.
608 std::vector<uint8_t> input;
609 if (!DecodeBase64(&input, input_b64)) {
610 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400611 }
612
David Benjamin1d77e562015-03-22 17:22:08 -0400613 // Verify the SSL_SESSION decodes.
David Benjaminef14b2d2015-11-11 14:01:27 -0800614 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400615 if (!session) {
616 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400617 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400618 }
619
David Benjamin1d77e562015-03-22 17:22:08 -0400620 // Verify the SSL_SESSION encoding round-trips.
621 size_t encoded_len;
Adam Langley10f97f32016-07-12 08:09:33 -0700622 ScopedOpenSSLBytes encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400623 uint8_t *encoded_raw;
624 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400625 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400626 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400627 }
David Benjamin1d77e562015-03-22 17:22:08 -0400628 encoded.reset(encoded_raw);
629 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800630 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400631 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200632 hexdump(stderr, "Before: ", input.data(), input.size());
633 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400634 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400635 }
David Benjamin3cac4502014-10-21 01:46:30 -0400636
David Benjaminfd67aa82015-06-15 19:41:48 -0400637 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800638 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400639 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800640 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400641 fprintf(stderr, "d2i_SSL_SESSION failed\n");
642 return false;
643 }
644
David Benjamin1d77e562015-03-22 17:22:08 -0400645 // Verify the SSL_SESSION encoding round-trips via the legacy API.
646 int len = i2d_SSL_SESSION(session.get(), NULL);
647 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400648 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400649 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400650 }
651
David Benjamin1d77e562015-03-22 17:22:08 -0400652 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
653 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400654 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400655 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400656 }
David Benjamin1d77e562015-03-22 17:22:08 -0400657
658 ptr = encoded.get();
659 len = i2d_SSL_SESSION(session.get(), &ptr);
660 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400661 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400662 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400663 }
David Benjamin1d77e562015-03-22 17:22:08 -0400664 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400665 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400666 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400667 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800668 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400669 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400670 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400671 }
672
David Benjamin1d77e562015-03-22 17:22:08 -0400673 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400674}
675
David Benjaminf297e022015-05-28 19:55:29 -0400676static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
677 std::vector<uint8_t> input;
678 if (!DecodeBase64(&input, input_b64)) {
679 return false;
680 }
681
682 // Verify that the SSL_SESSION fails to decode.
David Benjaminef14b2d2015-11-11 14:01:27 -0800683 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400684 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400685 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400686 return false;
687 }
688 ERR_clear_error();
689 return true;
690}
691
David Benjamin10e664b2016-06-20 22:20:47 -0400692static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400693 const SSL_METHOD *(*method)(void)) {
694 ScopedSSL_CTX ctx(SSL_CTX_new(method()));
695 if (!ctx) {
696 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500697 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400698 if (ctx->min_version != min_version || ctx->max_version != max_version) {
699 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
700 ctx->min_version, ctx->max_version, min_version, max_version);
701 return false;
702 }
703 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500704}
705
David Benjamin1d77e562015-03-22 17:22:08 -0400706static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500707 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
708 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400709 return false;
David Benjamin65226252015-02-05 16:49:47 -0500710 }
Adam Langley10f97f32016-07-12 08:09:33 -0700711 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400712 if (!rfc_name) {
713 return false;
714 }
David Benjamin67be0482015-04-20 16:19:00 -0400715 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400716 return true;
David Benjamin65226252015-02-05 16:49:47 -0500717}
718
719typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500720 int id;
David Benjamin65226252015-02-05 16:49:47 -0500721 const char *rfc_name;
722} CIPHER_RFC_NAME_TEST;
723
724static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500725 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
726 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
727 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500728 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
729 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
730 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500731 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
732 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
733 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
734 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
735 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
736 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
737 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
738 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
739 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
740 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
741 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Adam Langley85bc5602015-06-09 09:54:04 -0700742 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
743 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500744 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
745 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400746 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000747 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500748 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000749 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500750 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500751};
752
David Benjamin1d77e562015-03-22 17:22:08 -0400753static bool TestCipherGetRFCName(void) {
754 for (size_t i = 0;
755 i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500756 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400757 std::string rfc_name;
758 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
759 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
760 return false;
David Benjamin65226252015-02-05 16:49:47 -0500761 }
David Benjamin1d77e562015-03-22 17:22:08 -0400762 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500763 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400764 rfc_name.c_str(), test->rfc_name);
765 return false;
David Benjamin65226252015-02-05 16:49:47 -0500766 }
David Benjamin65226252015-02-05 16:49:47 -0500767 }
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return true;
David Benjamin65226252015-02-05 16:49:47 -0500769}
770
David Benjamin422fe082015-07-21 22:03:43 -0400771// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
772// replaced for one of length |ticket_len| or nullptr on failure.
773static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
774 std::vector<uint8_t> der;
775 if (!DecodeBase64(&der, kOpenSSLSession)) {
776 return nullptr;
777 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800778 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400779 if (!session) {
780 return nullptr;
781 }
782
783 // Swap out the ticket for a garbage one.
784 OPENSSL_free(session->tlsext_tick);
785 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
786 if (session->tlsext_tick == nullptr) {
787 return nullptr;
788 }
789 memset(session->tlsext_tick, 'a', ticket_len);
790 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400791
792 // Fix up the timeout.
793 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400794 return session;
795}
796
797// GetClientHelloLen creates a client SSL connection with a ticket of length
798// |ticket_len| and records the ClientHello. It returns the length of the
799// ClientHello, not including the record header, on success and zero on error.
800static size_t GetClientHelloLen(size_t ticket_len) {
801 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
802 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
803 if (!ctx || !session) {
804 return 0;
805 }
806 ScopedSSL ssl(SSL_new(ctx.get()));
807 ScopedBIO bio(BIO_new(BIO_s_mem()));
808 if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) {
809 return 0;
810 }
811 // Do not configure a reading BIO, but record what's written to a memory BIO.
812 SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get()));
813 int ret = SSL_connect(ssl.get());
814 if (ret > 0) {
815 // SSL_connect should fail without a BIO to write to.
816 return 0;
817 }
818 ERR_clear_error();
819
820 const uint8_t *unused;
821 size_t client_hello_len;
822 if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) ||
823 client_hello_len <= SSL3_RT_HEADER_LENGTH) {
824 return 0;
825 }
826 return client_hello_len - SSL3_RT_HEADER_LENGTH;
827}
828
829struct PaddingTest {
830 size_t input_len, padded_len;
831};
832
833static const PaddingTest kPaddingTests[] = {
834 // ClientHellos of length below 0x100 do not require padding.
835 {0xfe, 0xfe},
836 {0xff, 0xff},
837 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
838 {0x100, 0x200},
839 {0x123, 0x200},
840 {0x1fb, 0x200},
841 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
842 // padding extension takes a minimum of four bytes plus one required content
843 // byte. (To work around yet more server bugs, we avoid empty final
844 // extensions.)
845 {0x1fc, 0x201},
846 {0x1fd, 0x202},
847 {0x1fe, 0x203},
848 {0x1ff, 0x204},
849 // Finally, larger ClientHellos need no padding.
850 {0x200, 0x200},
851 {0x201, 0x201},
852};
853
854static bool TestPaddingExtension() {
855 // Sample a baseline length.
856 size_t base_len = GetClientHelloLen(1);
857 if (base_len == 0) {
858 return false;
859 }
860
861 for (const PaddingTest &test : kPaddingTests) {
862 if (base_len > test.input_len) {
863 fprintf(stderr, "Baseline ClientHello too long.\n");
864 return false;
865 }
866
867 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
868 if (padded_len != test.padded_len) {
869 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
870 static_cast<unsigned>(test.input_len),
871 static_cast<unsigned>(padded_len),
872 static_cast<unsigned>(test.padded_len));
873 return false;
874 }
875 }
876 return true;
877}
878
David Benjamin1d128f32015-09-08 17:41:40 -0400879// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
880// before configuring as a server.
881static bool TestClientCAList() {
882 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
883 if (!ctx) {
884 return false;
885 }
886 ScopedSSL ssl(SSL_new(ctx.get()));
887 if (!ssl) {
888 return false;
889 }
890
891 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
892 if (stack == nullptr) {
893 return false;
894 }
895 // |SSL_set_client_CA_list| takes ownership.
896 SSL_set_client_CA_list(ssl.get(), stack);
897
898 return SSL_get_client_CA_list(ssl.get()) == stack;
899}
900
David Benjamin0f653952015-10-18 14:28:01 -0400901static void AppendSession(SSL_SESSION *session, void *arg) {
902 std::vector<SSL_SESSION*> *out =
903 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
904 out->push_back(session);
905}
906
907// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
908// order.
909static bool ExpectCache(SSL_CTX *ctx,
910 const std::vector<SSL_SESSION*> &expected) {
911 // Check the linked list.
912 SSL_SESSION *ptr = ctx->session_cache_head;
913 for (SSL_SESSION *session : expected) {
914 if (ptr != session) {
915 return false;
916 }
917 // TODO(davidben): This is an absurd way to denote the end of the list.
918 if (ptr->next ==
919 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
920 ptr = nullptr;
921 } else {
922 ptr = ptr->next;
923 }
924 }
925 if (ptr != nullptr) {
926 return false;
927 }
928
929 // Check the hash table.
930 std::vector<SSL_SESSION*> actual, expected_copy;
931 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
932 expected_copy = expected;
933
934 std::sort(actual.begin(), actual.end());
935 std::sort(expected_copy.begin(), expected_copy.end());
936
937 return actual == expected_copy;
938}
939
940static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
941 ScopedSSL_SESSION ret(SSL_SESSION_new());
942 if (!ret) {
943 return nullptr;
944 }
945
946 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
947 memset(ret->session_id, 0, ret->session_id_length);
948 memcpy(ret->session_id, &number, sizeof(number));
949 return ret;
950}
951
David Benjamin0f653952015-10-18 14:28:01 -0400952// Test that the internal session cache behaves as expected.
953static bool TestInternalSessionCache() {
954 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
955 if (!ctx) {
956 return false;
957 }
958
959 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500960 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400961 for (int i = 0; i < 10; i++) {
962 ScopedSSL_SESSION session = CreateTestSession(i);
963 if (!session) {
964 return false;
965 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500966 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400967 }
968
969 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
970
971 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500972 for (const auto &session : sessions) {
973 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400974 return false;
975 }
976 }
977
978 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500979 std::vector<SSL_SESSION*> expected = {
980 sessions[9].get(),
981 sessions[8].get(),
982 sessions[7].get(),
983 sessions[6].get(),
984 sessions[5].get(),
985 };
David Benjamin0f653952015-10-18 14:28:01 -0400986 if (!ExpectCache(ctx.get(), expected)) {
987 return false;
988 }
989
990 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500991 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -0400992 !ExpectCache(ctx.get(), expected)) {
993 return false;
994 }
995
996 // Although collisions should be impossible (256-bit session IDs), the cache
997 // must handle them gracefully.
998 ScopedSSL_SESSION collision(CreateTestSession(7));
999 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1000 return false;
1001 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001002 expected = {
1003 collision.get(),
1004 sessions[9].get(),
1005 sessions[8].get(),
1006 sessions[6].get(),
1007 sessions[5].get(),
1008 };
David Benjamin0f653952015-10-18 14:28:01 -04001009 if (!ExpectCache(ctx.get(), expected)) {
1010 return false;
1011 }
1012
1013 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001014 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001015 return false;
1016 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001017 expected = {
1018 collision.get(),
1019 sessions[9].get(),
1020 sessions[8].get(),
1021 sessions[5].get(),
1022 };
David Benjamin0f653952015-10-18 14:28:01 -04001023 if (!ExpectCache(ctx.get(), expected)) {
1024 return false;
1025 }
1026
1027 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001028 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1029 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001030 !ExpectCache(ctx.get(), expected)) {
1031 return false;
1032 }
1033
1034 return true;
1035}
1036
David Benjaminde942382016-02-11 12:02:01 -05001037static uint16_t EpochFromSequence(uint64_t seq) {
1038 return static_cast<uint16_t>(seq >> 48);
1039}
1040
1041static ScopedX509 GetTestCertificate() {
1042 static const char kCertPEM[] =
1043 "-----BEGIN CERTIFICATE-----\n"
1044 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1045 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1046 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1047 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1048 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1049 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1050 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1051 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1052 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1053 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1054 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1055 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1056 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1057 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001058 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001059 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1060}
1061
1062static ScopedEVP_PKEY GetTestKey() {
1063 static const char kKeyPEM[] =
1064 "-----BEGIN RSA PRIVATE KEY-----\n"
1065 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1066 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1067 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1068 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1069 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1070 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1071 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1072 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1073 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1074 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1075 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1076 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1077 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1078 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001079 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001080 return ScopedEVP_PKEY(
1081 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1082}
1083
David Benjamin686bb192016-05-10 15:15:41 -04001084static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
1085 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1086 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001087 if (!client || !server) {
1088 return false;
1089 }
1090 SSL_set_connect_state(client.get());
1091 SSL_set_accept_state(server.get());
1092
1093 BIO *bio1, *bio2;
1094 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1095 return false;
1096 }
1097 // SSL_set_bio takes ownership.
1098 SSL_set_bio(client.get(), bio1, bio1);
1099 SSL_set_bio(server.get(), bio2, bio2);
1100
1101 // Drive both their handshakes to completion.
1102 for (;;) {
1103 int client_ret = SSL_do_handshake(client.get());
1104 int client_err = SSL_get_error(client.get(), client_ret);
1105 if (client_err != SSL_ERROR_NONE &&
1106 client_err != SSL_ERROR_WANT_READ &&
1107 client_err != SSL_ERROR_WANT_WRITE) {
1108 fprintf(stderr, "Client error: %d\n", client_err);
1109 return false;
1110 }
1111
1112 int server_ret = SSL_do_handshake(server.get());
1113 int server_err = SSL_get_error(server.get(), server_ret);
1114 if (server_err != SSL_ERROR_NONE &&
1115 server_err != SSL_ERROR_WANT_READ &&
1116 server_err != SSL_ERROR_WANT_WRITE) {
1117 fprintf(stderr, "Server error: %d\n", server_err);
1118 return false;
1119 }
1120
1121 if (client_ret == 1 && server_ret == 1) {
1122 break;
1123 }
1124 }
1125
David Benjamin686bb192016-05-10 15:15:41 -04001126 *out_client = std::move(client);
1127 *out_server = std::move(server);
1128 return true;
1129}
1130
1131static bool TestSequenceNumber(bool dtls) {
1132 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1133 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1134 if (!client_ctx || !server_ctx) {
1135 return false;
1136 }
1137
1138 ScopedX509 cert = GetTestCertificate();
1139 ScopedEVP_PKEY key = GetTestKey();
1140 if (!cert || !key ||
1141 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1142 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1143 return false;
1144 }
1145
1146 ScopedSSL client, server;
1147 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1148 server_ctx.get())) {
1149 return false;
1150 }
1151
David Benjaminde942382016-02-11 12:02:01 -05001152 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1153 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1154 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1155 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1156
1157 if (dtls) {
1158 // Both client and server must be at epoch 1.
1159 if (EpochFromSequence(client_read_seq) != 1 ||
1160 EpochFromSequence(client_write_seq) != 1 ||
1161 EpochFromSequence(server_read_seq) != 1 ||
1162 EpochFromSequence(server_write_seq) != 1) {
1163 fprintf(stderr, "Bad epochs.\n");
1164 return false;
1165 }
1166
1167 // The next record to be written should exceed the largest received.
1168 if (client_write_seq <= server_read_seq ||
1169 server_write_seq <= client_read_seq) {
1170 fprintf(stderr, "Inconsistent sequence numbers.\n");
1171 return false;
1172 }
1173 } else {
1174 // The next record to be written should equal the next to be received.
1175 if (client_write_seq != server_read_seq ||
1176 server_write_seq != client_write_seq) {
1177 fprintf(stderr, "Inconsistent sequence numbers.\n");
1178 return false;
1179 }
1180 }
1181
1182 // Send a record from client to server.
1183 uint8_t byte = 0;
1184 if (SSL_write(client.get(), &byte, 1) != 1 ||
1185 SSL_read(server.get(), &byte, 1) != 1) {
1186 fprintf(stderr, "Could not send byte.\n");
1187 return false;
1188 }
1189
1190 // The client write and server read sequence numbers should have incremented.
1191 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1192 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1193 fprintf(stderr, "Sequence numbers did not increment.\n");\
1194 return false;
1195 }
1196
1197 return true;
1198}
1199
David Benjamin686bb192016-05-10 15:15:41 -04001200static bool TestOneSidedShutdown() {
1201 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1202 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1203 if (!client_ctx || !server_ctx) {
1204 return false;
1205 }
1206
1207 ScopedX509 cert = GetTestCertificate();
1208 ScopedEVP_PKEY key = GetTestKey();
1209 if (!cert || !key ||
1210 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1211 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1212 return false;
1213 }
1214
1215 ScopedSSL client, server;
1216 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1217 server_ctx.get())) {
1218 return false;
1219 }
1220
1221 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1222 // one side has shut down.
1223 if (SSL_shutdown(client.get()) != 0) {
1224 fprintf(stderr, "Could not shutdown.\n");
1225 return false;
1226 }
1227
1228 // Reading from the server should consume the EOF.
1229 uint8_t byte;
1230 if (SSL_read(server.get(), &byte, 1) != 0 ||
1231 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1232 fprintf(stderr, "Connection was not shut down cleanly.\n");
1233 return false;
1234 }
1235
1236 // However, the server may continue to write data and then shut down the
1237 // connection.
1238 byte = 42;
1239 if (SSL_write(server.get(), &byte, 1) != 1 ||
1240 SSL_read(client.get(), &byte, 1) != 1 ||
1241 byte != 42) {
1242 fprintf(stderr, "Could not send byte.\n");
1243 return false;
1244 }
1245
1246 // The server may then shutdown the connection.
1247 if (SSL_shutdown(server.get()) != 1 ||
1248 SSL_shutdown(client.get()) != 1) {
1249 fprintf(stderr, "Could not complete shutdown.\n");
1250 return false;
1251 }
1252
1253 return true;
1254}
1255
David Benjamin5c0fb882016-06-14 14:03:51 -04001256static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1257 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1258 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1259 SSL_get_wfd(ssl), rfd, wfd);
1260 return false;
1261 }
1262
1263 // The wrapper BIOs are always equal when fds are equal, even if set
1264 // individually.
1265 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1266 fprintf(stderr, "rbio and wbio did not match.\n");
1267 return false;
1268 }
1269
1270 return true;
1271}
1272
1273static bool TestSetFD() {
1274 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1275 if (!ctx) {
1276 return false;
1277 }
1278
1279 // Test setting different read and write FDs.
1280 ScopedSSL ssl(SSL_new(ctx.get()));
1281 if (!ssl ||
1282 !SSL_set_rfd(ssl.get(), 1) ||
1283 !SSL_set_wfd(ssl.get(), 2) ||
1284 !ExpectFDs(ssl.get(), 1, 2)) {
1285 return false;
1286 }
1287
1288 // Test setting the same FD.
1289 ssl.reset(SSL_new(ctx.get()));
1290 if (!ssl ||
1291 !SSL_set_fd(ssl.get(), 1) ||
1292 !ExpectFDs(ssl.get(), 1, 1)) {
1293 return false;
1294 }
1295
1296 // Test setting the same FD one side at a time.
1297 ssl.reset(SSL_new(ctx.get()));
1298 if (!ssl ||
1299 !SSL_set_rfd(ssl.get(), 1) ||
1300 !SSL_set_wfd(ssl.get(), 1) ||
1301 !ExpectFDs(ssl.get(), 1, 1)) {
1302 return false;
1303 }
1304
1305 // Test setting the same FD in the other order.
1306 ssl.reset(SSL_new(ctx.get()));
1307 if (!ssl ||
1308 !SSL_set_wfd(ssl.get(), 1) ||
1309 !SSL_set_rfd(ssl.get(), 1) ||
1310 !ExpectFDs(ssl.get(), 1, 1)) {
1311 return false;
1312 }
1313
David Benjamin5c0fb882016-06-14 14:03:51 -04001314 // Test changing the read FD partway through.
1315 ssl.reset(SSL_new(ctx.get()));
1316 if (!ssl ||
1317 !SSL_set_fd(ssl.get(), 1) ||
1318 !SSL_set_rfd(ssl.get(), 2) ||
1319 !ExpectFDs(ssl.get(), 2, 1)) {
1320 return false;
1321 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001322
1323 // Test changing the write FD partway through.
1324 ssl.reset(SSL_new(ctx.get()));
1325 if (!ssl ||
1326 !SSL_set_fd(ssl.get(), 1) ||
1327 !SSL_set_wfd(ssl.get(), 2) ||
1328 !ExpectFDs(ssl.get(), 1, 2)) {
1329 return false;
1330 }
1331
1332 // Test a no-op change to the read FD partway through.
1333 ssl.reset(SSL_new(ctx.get()));
1334 if (!ssl ||
1335 !SSL_set_fd(ssl.get(), 1) ||
1336 !SSL_set_rfd(ssl.get(), 1) ||
1337 !ExpectFDs(ssl.get(), 1, 1)) {
1338 return false;
1339 }
1340
1341 // Test a no-op change to the write FD partway through.
1342 ssl.reset(SSL_new(ctx.get()));
1343 if (!ssl ||
1344 !SSL_set_fd(ssl.get(), 1) ||
1345 !SSL_set_wfd(ssl.get(), 1) ||
1346 !ExpectFDs(ssl.get(), 1, 1)) {
1347 return false;
1348 }
1349
1350 // ASan builds will implicitly test that the internal |BIO| reference-counting
1351 // is correct.
1352
1353 return true;
1354}
1355
David Benjamin1d128f32015-09-08 17:41:40 -04001356int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04001357 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04001358
Adam Langley10f97f32016-07-12 08:09:33 -07001359 if (!TestCipherRules() ||
1360 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
1361 !TestSSL_SESSIONEncoding(kCustomSession) ||
1362 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
1363 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
1364 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
1365 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04001366 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07001367 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
1368 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
1369 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
1370 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
1371 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
1372 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
1373 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
1374 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
1375 !TestCipherGetRFCName() ||
1376 !TestPaddingExtension() ||
1377 !TestClientCAList() ||
1378 !TestInternalSessionCache() ||
1379 !TestSequenceNumber(false /* TLS */) ||
1380 !TestSequenceNumber(true /* DTLS */) ||
1381 !TestOneSidedShutdown() ||
1382 !TestSetFD()) {
Brian Smith83a82982015-04-09 16:21:10 -10001383 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04001384 return 1;
1385 }
1386
David Benjamin2e521212014-07-16 14:37:51 -04001387 printf("PASS\n");
1388 return 0;
1389}