blob: b6d4fd6e293c4576eca09b98f401241f0df8f5fb [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
David Benjamin1d77e562015-03-22 17:22:08 -040032#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
David Benjamin1d77e562015-03-22 17:22:08 -0400404// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
405// s_client -sess_out.
David Benjamin751e8892014-10-19 00:59:36 -0400406static const char kOpenSSLSession[] =
David Benjamin688d8df2014-11-02 23:06:42 -0500407 "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";
David Benjamin751e8892014-10-19 00:59:36 -0400438
David Benjamin1d77e562015-03-22 17:22:08 -0400439// 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.
David Benjamin751e8892014-10-19 00:59:36 -0400442static const char kCustomSession[] =
David Benjamin688d8df2014-11-02 23:06:42 -0500443 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
444 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
445 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
446 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
447 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
448 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
449 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
450 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
David Benjamin751e8892014-10-19 00:59:36 -0400451
David Benjamin26416e92015-08-22 16:04:17 -0400452// 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
David Benjaminf297e022015-05-28 19:55:29 -0400550// 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
David Benjamin338e0672015-05-28 20:00:08 -0400562// 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
David Benjaminfd67aa82015-06-15 19:41:48 -0400574// 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;
622 ScopedOpenSSLBytes encoded;
623 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 Benjamin10e664b2016-06-20 22:20:47 -0400698 return ctx->min_version == min_version && ctx->max_version == max_version;
David Benjamin82c9e902014-12-12 15:55:27 -0500699}
700
David Benjamin1d77e562015-03-22 17:22:08 -0400701static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500702 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
703 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400704 return false;
David Benjamin65226252015-02-05 16:49:47 -0500705 }
David Benjamin67be0482015-04-20 16:19:00 -0400706 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400707 if (!rfc_name) {
708 return false;
709 }
David Benjamin67be0482015-04-20 16:19:00 -0400710 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400711 return true;
David Benjamin65226252015-02-05 16:49:47 -0500712}
713
714typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500715 int id;
David Benjamin65226252015-02-05 16:49:47 -0500716 const char *rfc_name;
717} CIPHER_RFC_NAME_TEST;
718
719static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500720 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
721 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
722 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500723 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
724 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
725 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500726 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
727 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
728 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
729 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
730 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
731 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
732 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
733 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
734 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
735 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
736 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Adam Langley85bc5602015-06-09 09:54:04 -0700737 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
738 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500739 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
740 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400741 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000742 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500743 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000744 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500745 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500746};
747
David Benjamin1d77e562015-03-22 17:22:08 -0400748static bool TestCipherGetRFCName(void) {
749 for (size_t i = 0;
750 i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500751 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400752 std::string rfc_name;
753 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
754 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
755 return false;
David Benjamin65226252015-02-05 16:49:47 -0500756 }
David Benjamin1d77e562015-03-22 17:22:08 -0400757 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500758 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400759 rfc_name.c_str(), test->rfc_name);
760 return false;
David Benjamin65226252015-02-05 16:49:47 -0500761 }
David Benjamin65226252015-02-05 16:49:47 -0500762 }
David Benjamin1d77e562015-03-22 17:22:08 -0400763 return true;
David Benjamin65226252015-02-05 16:49:47 -0500764}
765
David Benjamin422fe082015-07-21 22:03:43 -0400766// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
767// replaced for one of length |ticket_len| or nullptr on failure.
768static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
769 std::vector<uint8_t> der;
770 if (!DecodeBase64(&der, kOpenSSLSession)) {
771 return nullptr;
772 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800773 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400774 if (!session) {
775 return nullptr;
776 }
777
778 // Swap out the ticket for a garbage one.
779 OPENSSL_free(session->tlsext_tick);
780 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
781 if (session->tlsext_tick == nullptr) {
782 return nullptr;
783 }
784 memset(session->tlsext_tick, 'a', ticket_len);
785 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400786
787 // Fix up the timeout.
788 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400789 return session;
790}
791
792// GetClientHelloLen creates a client SSL connection with a ticket of length
793// |ticket_len| and records the ClientHello. It returns the length of the
794// ClientHello, not including the record header, on success and zero on error.
795static size_t GetClientHelloLen(size_t ticket_len) {
796 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
797 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
798 if (!ctx || !session) {
799 return 0;
800 }
801 ScopedSSL ssl(SSL_new(ctx.get()));
802 ScopedBIO bio(BIO_new(BIO_s_mem()));
803 if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) {
804 return 0;
805 }
806 // Do not configure a reading BIO, but record what's written to a memory BIO.
807 SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get()));
808 int ret = SSL_connect(ssl.get());
809 if (ret > 0) {
810 // SSL_connect should fail without a BIO to write to.
811 return 0;
812 }
813 ERR_clear_error();
814
815 const uint8_t *unused;
816 size_t client_hello_len;
817 if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) ||
818 client_hello_len <= SSL3_RT_HEADER_LENGTH) {
819 return 0;
820 }
821 return client_hello_len - SSL3_RT_HEADER_LENGTH;
822}
823
824struct PaddingTest {
825 size_t input_len, padded_len;
826};
827
828static const PaddingTest kPaddingTests[] = {
829 // ClientHellos of length below 0x100 do not require padding.
830 {0xfe, 0xfe},
831 {0xff, 0xff},
832 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
833 {0x100, 0x200},
834 {0x123, 0x200},
835 {0x1fb, 0x200},
836 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
837 // padding extension takes a minimum of four bytes plus one required content
838 // byte. (To work around yet more server bugs, we avoid empty final
839 // extensions.)
840 {0x1fc, 0x201},
841 {0x1fd, 0x202},
842 {0x1fe, 0x203},
843 {0x1ff, 0x204},
844 // Finally, larger ClientHellos need no padding.
845 {0x200, 0x200},
846 {0x201, 0x201},
847};
848
849static bool TestPaddingExtension() {
850 // Sample a baseline length.
851 size_t base_len = GetClientHelloLen(1);
852 if (base_len == 0) {
853 return false;
854 }
855
856 for (const PaddingTest &test : kPaddingTests) {
857 if (base_len > test.input_len) {
858 fprintf(stderr, "Baseline ClientHello too long.\n");
859 return false;
860 }
861
862 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
863 if (padded_len != test.padded_len) {
864 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
865 static_cast<unsigned>(test.input_len),
866 static_cast<unsigned>(padded_len),
867 static_cast<unsigned>(test.padded_len));
868 return false;
869 }
870 }
871 return true;
872}
873
David Benjamin1d128f32015-09-08 17:41:40 -0400874// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
875// before configuring as a server.
876static bool TestClientCAList() {
877 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
878 if (!ctx) {
879 return false;
880 }
881 ScopedSSL ssl(SSL_new(ctx.get()));
882 if (!ssl) {
883 return false;
884 }
885
886 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
887 if (stack == nullptr) {
888 return false;
889 }
890 // |SSL_set_client_CA_list| takes ownership.
891 SSL_set_client_CA_list(ssl.get(), stack);
892
893 return SSL_get_client_CA_list(ssl.get()) == stack;
894}
895
David Benjamin0f653952015-10-18 14:28:01 -0400896static void AppendSession(SSL_SESSION *session, void *arg) {
897 std::vector<SSL_SESSION*> *out =
898 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
899 out->push_back(session);
900}
901
902// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
903// order.
904static bool ExpectCache(SSL_CTX *ctx,
905 const std::vector<SSL_SESSION*> &expected) {
906 // Check the linked list.
907 SSL_SESSION *ptr = ctx->session_cache_head;
908 for (SSL_SESSION *session : expected) {
909 if (ptr != session) {
910 return false;
911 }
912 // TODO(davidben): This is an absurd way to denote the end of the list.
913 if (ptr->next ==
914 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
915 ptr = nullptr;
916 } else {
917 ptr = ptr->next;
918 }
919 }
920 if (ptr != nullptr) {
921 return false;
922 }
923
924 // Check the hash table.
925 std::vector<SSL_SESSION*> actual, expected_copy;
926 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
927 expected_copy = expected;
928
929 std::sort(actual.begin(), actual.end());
930 std::sort(expected_copy.begin(), expected_copy.end());
931
932 return actual == expected_copy;
933}
934
935static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
936 ScopedSSL_SESSION ret(SSL_SESSION_new());
937 if (!ret) {
938 return nullptr;
939 }
940
941 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
942 memset(ret->session_id, 0, ret->session_id_length);
943 memcpy(ret->session_id, &number, sizeof(number));
944 return ret;
945}
946
David Benjamin0f653952015-10-18 14:28:01 -0400947// Test that the internal session cache behaves as expected.
948static bool TestInternalSessionCache() {
949 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
950 if (!ctx) {
951 return false;
952 }
953
954 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500955 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400956 for (int i = 0; i < 10; i++) {
957 ScopedSSL_SESSION session = CreateTestSession(i);
958 if (!session) {
959 return false;
960 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500961 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400962 }
963
964 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
965
966 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500967 for (const auto &session : sessions) {
968 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400969 return false;
970 }
971 }
972
973 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500974 std::vector<SSL_SESSION*> expected = {
975 sessions[9].get(),
976 sessions[8].get(),
977 sessions[7].get(),
978 sessions[6].get(),
979 sessions[5].get(),
980 };
David Benjamin0f653952015-10-18 14:28:01 -0400981 if (!ExpectCache(ctx.get(), expected)) {
982 return false;
983 }
984
985 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500986 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -0400987 !ExpectCache(ctx.get(), expected)) {
988 return false;
989 }
990
991 // Although collisions should be impossible (256-bit session IDs), the cache
992 // must handle them gracefully.
993 ScopedSSL_SESSION collision(CreateTestSession(7));
994 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
995 return false;
996 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500997 expected = {
998 collision.get(),
999 sessions[9].get(),
1000 sessions[8].get(),
1001 sessions[6].get(),
1002 sessions[5].get(),
1003 };
David Benjamin0f653952015-10-18 14:28:01 -04001004 if (!ExpectCache(ctx.get(), expected)) {
1005 return false;
1006 }
1007
1008 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001009 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001010 return false;
1011 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001012 expected = {
1013 collision.get(),
1014 sessions[9].get(),
1015 sessions[8].get(),
1016 sessions[5].get(),
1017 };
David Benjamin0f653952015-10-18 14:28:01 -04001018 if (!ExpectCache(ctx.get(), expected)) {
1019 return false;
1020 }
1021
1022 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001023 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1024 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001025 !ExpectCache(ctx.get(), expected)) {
1026 return false;
1027 }
1028
1029 return true;
1030}
1031
David Benjaminde942382016-02-11 12:02:01 -05001032static uint16_t EpochFromSequence(uint64_t seq) {
1033 return static_cast<uint16_t>(seq >> 48);
1034}
1035
1036static ScopedX509 GetTestCertificate() {
1037 static const char kCertPEM[] =
1038 "-----BEGIN CERTIFICATE-----\n"
1039 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1040 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1041 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1042 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1043 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1044 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1045 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1046 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1047 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1048 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1049 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1050 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1051 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1052 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001053 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001054 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1055}
1056
1057static ScopedEVP_PKEY GetTestKey() {
1058 static const char kKeyPEM[] =
1059 "-----BEGIN RSA PRIVATE KEY-----\n"
1060 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1061 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1062 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1063 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1064 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1065 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1066 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1067 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1068 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1069 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1070 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1071 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1072 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1073 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001074 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001075 return ScopedEVP_PKEY(
1076 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1077}
1078
David Benjamin686bb192016-05-10 15:15:41 -04001079static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
1080 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1081 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001082 if (!client || !server) {
1083 return false;
1084 }
1085 SSL_set_connect_state(client.get());
1086 SSL_set_accept_state(server.get());
1087
1088 BIO *bio1, *bio2;
1089 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1090 return false;
1091 }
1092 // SSL_set_bio takes ownership.
1093 SSL_set_bio(client.get(), bio1, bio1);
1094 SSL_set_bio(server.get(), bio2, bio2);
1095
1096 // Drive both their handshakes to completion.
1097 for (;;) {
1098 int client_ret = SSL_do_handshake(client.get());
1099 int client_err = SSL_get_error(client.get(), client_ret);
1100 if (client_err != SSL_ERROR_NONE &&
1101 client_err != SSL_ERROR_WANT_READ &&
1102 client_err != SSL_ERROR_WANT_WRITE) {
1103 fprintf(stderr, "Client error: %d\n", client_err);
1104 return false;
1105 }
1106
1107 int server_ret = SSL_do_handshake(server.get());
1108 int server_err = SSL_get_error(server.get(), server_ret);
1109 if (server_err != SSL_ERROR_NONE &&
1110 server_err != SSL_ERROR_WANT_READ &&
1111 server_err != SSL_ERROR_WANT_WRITE) {
1112 fprintf(stderr, "Server error: %d\n", server_err);
1113 return false;
1114 }
1115
1116 if (client_ret == 1 && server_ret == 1) {
1117 break;
1118 }
1119 }
1120
David Benjamin686bb192016-05-10 15:15:41 -04001121 *out_client = std::move(client);
1122 *out_server = std::move(server);
1123 return true;
1124}
1125
1126static bool TestSequenceNumber(bool dtls) {
1127 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1128 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1129 if (!client_ctx || !server_ctx) {
1130 return false;
1131 }
1132
1133 ScopedX509 cert = GetTestCertificate();
1134 ScopedEVP_PKEY key = GetTestKey();
1135 if (!cert || !key ||
1136 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1137 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1138 return false;
1139 }
1140
1141 ScopedSSL client, server;
1142 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1143 server_ctx.get())) {
1144 return false;
1145 }
1146
David Benjaminde942382016-02-11 12:02:01 -05001147 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1148 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1149 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1150 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1151
1152 if (dtls) {
1153 // Both client and server must be at epoch 1.
1154 if (EpochFromSequence(client_read_seq) != 1 ||
1155 EpochFromSequence(client_write_seq) != 1 ||
1156 EpochFromSequence(server_read_seq) != 1 ||
1157 EpochFromSequence(server_write_seq) != 1) {
1158 fprintf(stderr, "Bad epochs.\n");
1159 return false;
1160 }
1161
1162 // The next record to be written should exceed the largest received.
1163 if (client_write_seq <= server_read_seq ||
1164 server_write_seq <= client_read_seq) {
1165 fprintf(stderr, "Inconsistent sequence numbers.\n");
1166 return false;
1167 }
1168 } else {
1169 // The next record to be written should equal the next to be received.
1170 if (client_write_seq != server_read_seq ||
1171 server_write_seq != client_write_seq) {
1172 fprintf(stderr, "Inconsistent sequence numbers.\n");
1173 return false;
1174 }
1175 }
1176
1177 // Send a record from client to server.
1178 uint8_t byte = 0;
1179 if (SSL_write(client.get(), &byte, 1) != 1 ||
1180 SSL_read(server.get(), &byte, 1) != 1) {
1181 fprintf(stderr, "Could not send byte.\n");
1182 return false;
1183 }
1184
1185 // The client write and server read sequence numbers should have incremented.
1186 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1187 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1188 fprintf(stderr, "Sequence numbers did not increment.\n");\
1189 return false;
1190 }
1191
1192 return true;
1193}
1194
David Benjamin686bb192016-05-10 15:15:41 -04001195static bool TestOneSidedShutdown() {
1196 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1197 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1198 if (!client_ctx || !server_ctx) {
1199 return false;
1200 }
1201
1202 ScopedX509 cert = GetTestCertificate();
1203 ScopedEVP_PKEY key = GetTestKey();
1204 if (!cert || !key ||
1205 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1206 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1207 return false;
1208 }
1209
1210 ScopedSSL client, server;
1211 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1212 server_ctx.get())) {
1213 return false;
1214 }
1215
1216 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1217 // one side has shut down.
1218 if (SSL_shutdown(client.get()) != 0) {
1219 fprintf(stderr, "Could not shutdown.\n");
1220 return false;
1221 }
1222
1223 // Reading from the server should consume the EOF.
1224 uint8_t byte;
1225 if (SSL_read(server.get(), &byte, 1) != 0 ||
1226 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1227 fprintf(stderr, "Connection was not shut down cleanly.\n");
1228 return false;
1229 }
1230
1231 // However, the server may continue to write data and then shut down the
1232 // connection.
1233 byte = 42;
1234 if (SSL_write(server.get(), &byte, 1) != 1 ||
1235 SSL_read(client.get(), &byte, 1) != 1 ||
1236 byte != 42) {
1237 fprintf(stderr, "Could not send byte.\n");
1238 return false;
1239 }
1240
1241 // The server may then shutdown the connection.
1242 if (SSL_shutdown(server.get()) != 1 ||
1243 SSL_shutdown(client.get()) != 1) {
1244 fprintf(stderr, "Could not complete shutdown.\n");
1245 return false;
1246 }
1247
1248 return true;
1249}
1250
David Benjamin5c0fb882016-06-14 14:03:51 -04001251static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1252 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1253 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1254 SSL_get_wfd(ssl), rfd, wfd);
1255 return false;
1256 }
1257
1258 // The wrapper BIOs are always equal when fds are equal, even if set
1259 // individually.
1260 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1261 fprintf(stderr, "rbio and wbio did not match.\n");
1262 return false;
1263 }
1264
1265 return true;
1266}
1267
1268static bool TestSetFD() {
1269 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1270 if (!ctx) {
1271 return false;
1272 }
1273
1274 // Test setting different read and write FDs.
1275 ScopedSSL ssl(SSL_new(ctx.get()));
1276 if (!ssl ||
1277 !SSL_set_rfd(ssl.get(), 1) ||
1278 !SSL_set_wfd(ssl.get(), 2) ||
1279 !ExpectFDs(ssl.get(), 1, 2)) {
1280 return false;
1281 }
1282
1283 // Test setting the same FD.
1284 ssl.reset(SSL_new(ctx.get()));
1285 if (!ssl ||
1286 !SSL_set_fd(ssl.get(), 1) ||
1287 !ExpectFDs(ssl.get(), 1, 1)) {
1288 return false;
1289 }
1290
1291 // Test setting the same FD one side at a time.
1292 ssl.reset(SSL_new(ctx.get()));
1293 if (!ssl ||
1294 !SSL_set_rfd(ssl.get(), 1) ||
1295 !SSL_set_wfd(ssl.get(), 1) ||
1296 !ExpectFDs(ssl.get(), 1, 1)) {
1297 return false;
1298 }
1299
1300 // Test setting the same FD in the other order.
1301 ssl.reset(SSL_new(ctx.get()));
1302 if (!ssl ||
1303 !SSL_set_wfd(ssl.get(), 1) ||
1304 !SSL_set_rfd(ssl.get(), 1) ||
1305 !ExpectFDs(ssl.get(), 1, 1)) {
1306 return false;
1307 }
1308
David Benjamin5c0fb882016-06-14 14:03:51 -04001309 // Test changing the read FD partway through.
1310 ssl.reset(SSL_new(ctx.get()));
1311 if (!ssl ||
1312 !SSL_set_fd(ssl.get(), 1) ||
1313 !SSL_set_rfd(ssl.get(), 2) ||
1314 !ExpectFDs(ssl.get(), 2, 1)) {
1315 return false;
1316 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001317
1318 // Test changing the write FD partway through.
1319 ssl.reset(SSL_new(ctx.get()));
1320 if (!ssl ||
1321 !SSL_set_fd(ssl.get(), 1) ||
1322 !SSL_set_wfd(ssl.get(), 2) ||
1323 !ExpectFDs(ssl.get(), 1, 2)) {
1324 return false;
1325 }
1326
1327 // Test a no-op change to the read FD partway through.
1328 ssl.reset(SSL_new(ctx.get()));
1329 if (!ssl ||
1330 !SSL_set_fd(ssl.get(), 1) ||
1331 !SSL_set_rfd(ssl.get(), 1) ||
1332 !ExpectFDs(ssl.get(), 1, 1)) {
1333 return false;
1334 }
1335
1336 // Test a no-op change to the write FD partway through.
1337 ssl.reset(SSL_new(ctx.get()));
1338 if (!ssl ||
1339 !SSL_set_fd(ssl.get(), 1) ||
1340 !SSL_set_wfd(ssl.get(), 1) ||
1341 !ExpectFDs(ssl.get(), 1, 1)) {
1342 return false;
1343 }
1344
1345 // ASan builds will implicitly test that the internal |BIO| reference-counting
1346 // is correct.
1347
1348 return true;
1349}
1350
David Benjamin1d128f32015-09-08 17:41:40 -04001351int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04001352 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04001353
David Benjamin1d77e562015-03-22 17:22:08 -04001354 if (!TestCipherRules() ||
1355 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
1356 !TestSSL_SESSIONEncoding(kCustomSession) ||
David Benjamin26416e92015-08-22 16:04:17 -04001357 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
David Benjaminf297e022015-05-28 19:55:29 -04001358 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
David Benjamin338e0672015-05-28 20:00:08 -04001359 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
David Benjaminfd67aa82015-06-15 19:41:48 -04001360 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04001361 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
1362 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
1363 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
1364 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
1365 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
1366 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
1367 !TestDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method) ||
1368 !TestDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method) ||
1369 !TestDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method) ||
David Benjamin422fe082015-07-21 22:03:43 -04001370 !TestCipherGetRFCName() ||
David Benjamin1d128f32015-09-08 17:41:40 -04001371 !TestPaddingExtension() ||
David Benjamin0f653952015-10-18 14:28:01 -04001372 !TestClientCAList() ||
David Benjaminde942382016-02-11 12:02:01 -05001373 !TestInternalSessionCache() ||
1374 !TestSequenceNumber(false /* TLS */) ||
David Benjamin686bb192016-05-10 15:15:41 -04001375 !TestSequenceNumber(true /* DTLS */) ||
David Benjamin5c0fb882016-06-14 14:03:51 -04001376 !TestOneSidedShutdown() ||
1377 !TestSetFD()) {
Brian Smith83a82982015-04-09 16:21:10 -10001378 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04001379 return 1;
1380 }
1381
David Benjamin2e521212014-07-16 14:37:51 -04001382 printf("PASS\n");
1383 return 0;
1384}