blob: ef389021bb226792e83a85a29ab3c3cbd8f270a0 [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 Benjamin1d77e562015-03-22 17:22:08 -0400692static bool TestDefaultVersion(uint16_t version,
693 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 }
Steven Valdez4f94b1c2016-05-24 12:31:07 -0400698 // TODO(svaldez): Remove TLS1_2_VERSION fallback upon implementing TLS 1.3.
699 return ctx->min_version == version &&
700 (ctx->max_version == version ||
701 (version == 0 && ctx->max_version == TLS1_2_VERSION));
David Benjamin82c9e902014-12-12 15:55:27 -0500702}
703
David Benjamin1d77e562015-03-22 17:22:08 -0400704static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500705 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
706 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400707 return false;
David Benjamin65226252015-02-05 16:49:47 -0500708 }
David Benjamin67be0482015-04-20 16:19:00 -0400709 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400710 if (!rfc_name) {
711 return false;
712 }
David Benjamin67be0482015-04-20 16:19:00 -0400713 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400714 return true;
David Benjamin65226252015-02-05 16:49:47 -0500715}
716
717typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500718 int id;
David Benjamin65226252015-02-05 16:49:47 -0500719 const char *rfc_name;
720} CIPHER_RFC_NAME_TEST;
721
722static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500723 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
724 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
725 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500726 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
727 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
728 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500729 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
730 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
731 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
732 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
733 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
734 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
735 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
736 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
737 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
738 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
739 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Adam Langley85bc5602015-06-09 09:54:04 -0700740 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
741 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500742 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
743 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400744 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000745 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500746 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000747 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500748 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500749};
750
David Benjamin1d77e562015-03-22 17:22:08 -0400751static bool TestCipherGetRFCName(void) {
752 for (size_t i = 0;
753 i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500754 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400755 std::string rfc_name;
756 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
757 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
758 return false;
David Benjamin65226252015-02-05 16:49:47 -0500759 }
David Benjamin1d77e562015-03-22 17:22:08 -0400760 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500761 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400762 rfc_name.c_str(), test->rfc_name);
763 return false;
David Benjamin65226252015-02-05 16:49:47 -0500764 }
David Benjamin65226252015-02-05 16:49:47 -0500765 }
David Benjamin1d77e562015-03-22 17:22:08 -0400766 return true;
David Benjamin65226252015-02-05 16:49:47 -0500767}
768
David Benjamin422fe082015-07-21 22:03:43 -0400769// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
770// replaced for one of length |ticket_len| or nullptr on failure.
771static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
772 std::vector<uint8_t> der;
773 if (!DecodeBase64(&der, kOpenSSLSession)) {
774 return nullptr;
775 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800776 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400777 if (!session) {
778 return nullptr;
779 }
780
781 // Swap out the ticket for a garbage one.
782 OPENSSL_free(session->tlsext_tick);
783 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
784 if (session->tlsext_tick == nullptr) {
785 return nullptr;
786 }
787 memset(session->tlsext_tick, 'a', ticket_len);
788 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400789
790 // Fix up the timeout.
791 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400792 return session;
793}
794
795// GetClientHelloLen creates a client SSL connection with a ticket of length
796// |ticket_len| and records the ClientHello. It returns the length of the
797// ClientHello, not including the record header, on success and zero on error.
798static size_t GetClientHelloLen(size_t ticket_len) {
799 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
800 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
801 if (!ctx || !session) {
802 return 0;
803 }
804 ScopedSSL ssl(SSL_new(ctx.get()));
805 ScopedBIO bio(BIO_new(BIO_s_mem()));
806 if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) {
807 return 0;
808 }
809 // Do not configure a reading BIO, but record what's written to a memory BIO.
810 SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get()));
811 int ret = SSL_connect(ssl.get());
812 if (ret > 0) {
813 // SSL_connect should fail without a BIO to write to.
814 return 0;
815 }
816 ERR_clear_error();
817
818 const uint8_t *unused;
819 size_t client_hello_len;
820 if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) ||
821 client_hello_len <= SSL3_RT_HEADER_LENGTH) {
822 return 0;
823 }
824 return client_hello_len - SSL3_RT_HEADER_LENGTH;
825}
826
827struct PaddingTest {
828 size_t input_len, padded_len;
829};
830
831static const PaddingTest kPaddingTests[] = {
832 // ClientHellos of length below 0x100 do not require padding.
833 {0xfe, 0xfe},
834 {0xff, 0xff},
835 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
836 {0x100, 0x200},
837 {0x123, 0x200},
838 {0x1fb, 0x200},
839 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
840 // padding extension takes a minimum of four bytes plus one required content
841 // byte. (To work around yet more server bugs, we avoid empty final
842 // extensions.)
843 {0x1fc, 0x201},
844 {0x1fd, 0x202},
845 {0x1fe, 0x203},
846 {0x1ff, 0x204},
847 // Finally, larger ClientHellos need no padding.
848 {0x200, 0x200},
849 {0x201, 0x201},
850};
851
852static bool TestPaddingExtension() {
853 // Sample a baseline length.
854 size_t base_len = GetClientHelloLen(1);
855 if (base_len == 0) {
856 return false;
857 }
858
859 for (const PaddingTest &test : kPaddingTests) {
860 if (base_len > test.input_len) {
861 fprintf(stderr, "Baseline ClientHello too long.\n");
862 return false;
863 }
864
865 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
866 if (padded_len != test.padded_len) {
867 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
868 static_cast<unsigned>(test.input_len),
869 static_cast<unsigned>(padded_len),
870 static_cast<unsigned>(test.padded_len));
871 return false;
872 }
873 }
874 return true;
875}
876
David Benjamin1d128f32015-09-08 17:41:40 -0400877// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
878// before configuring as a server.
879static bool TestClientCAList() {
880 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
881 if (!ctx) {
882 return false;
883 }
884 ScopedSSL ssl(SSL_new(ctx.get()));
885 if (!ssl) {
886 return false;
887 }
888
889 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
890 if (stack == nullptr) {
891 return false;
892 }
893 // |SSL_set_client_CA_list| takes ownership.
894 SSL_set_client_CA_list(ssl.get(), stack);
895
896 return SSL_get_client_CA_list(ssl.get()) == stack;
897}
898
David Benjamin0f653952015-10-18 14:28:01 -0400899static void AppendSession(SSL_SESSION *session, void *arg) {
900 std::vector<SSL_SESSION*> *out =
901 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
902 out->push_back(session);
903}
904
905// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
906// order.
907static bool ExpectCache(SSL_CTX *ctx,
908 const std::vector<SSL_SESSION*> &expected) {
909 // Check the linked list.
910 SSL_SESSION *ptr = ctx->session_cache_head;
911 for (SSL_SESSION *session : expected) {
912 if (ptr != session) {
913 return false;
914 }
915 // TODO(davidben): This is an absurd way to denote the end of the list.
916 if (ptr->next ==
917 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
918 ptr = nullptr;
919 } else {
920 ptr = ptr->next;
921 }
922 }
923 if (ptr != nullptr) {
924 return false;
925 }
926
927 // Check the hash table.
928 std::vector<SSL_SESSION*> actual, expected_copy;
929 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
930 expected_copy = expected;
931
932 std::sort(actual.begin(), actual.end());
933 std::sort(expected_copy.begin(), expected_copy.end());
934
935 return actual == expected_copy;
936}
937
938static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
939 ScopedSSL_SESSION ret(SSL_SESSION_new());
940 if (!ret) {
941 return nullptr;
942 }
943
944 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
945 memset(ret->session_id, 0, ret->session_id_length);
946 memcpy(ret->session_id, &number, sizeof(number));
947 return ret;
948}
949
David Benjamin0f653952015-10-18 14:28:01 -0400950// Test that the internal session cache behaves as expected.
951static bool TestInternalSessionCache() {
952 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
953 if (!ctx) {
954 return false;
955 }
956
957 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500958 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400959 for (int i = 0; i < 10; i++) {
960 ScopedSSL_SESSION session = CreateTestSession(i);
961 if (!session) {
962 return false;
963 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500964 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400965 }
966
967 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
968
969 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500970 for (const auto &session : sessions) {
971 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400972 return false;
973 }
974 }
975
976 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500977 std::vector<SSL_SESSION*> expected = {
978 sessions[9].get(),
979 sessions[8].get(),
980 sessions[7].get(),
981 sessions[6].get(),
982 sessions[5].get(),
983 };
David Benjamin0f653952015-10-18 14:28:01 -0400984 if (!ExpectCache(ctx.get(), expected)) {
985 return false;
986 }
987
988 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500989 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -0400990 !ExpectCache(ctx.get(), expected)) {
991 return false;
992 }
993
994 // Although collisions should be impossible (256-bit session IDs), the cache
995 // must handle them gracefully.
996 ScopedSSL_SESSION collision(CreateTestSession(7));
997 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
998 return false;
999 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001000 expected = {
1001 collision.get(),
1002 sessions[9].get(),
1003 sessions[8].get(),
1004 sessions[6].get(),
1005 sessions[5].get(),
1006 };
David Benjamin0f653952015-10-18 14:28:01 -04001007 if (!ExpectCache(ctx.get(), expected)) {
1008 return false;
1009 }
1010
1011 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001012 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001013 return false;
1014 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001015 expected = {
1016 collision.get(),
1017 sessions[9].get(),
1018 sessions[8].get(),
1019 sessions[5].get(),
1020 };
David Benjamin0f653952015-10-18 14:28:01 -04001021 if (!ExpectCache(ctx.get(), expected)) {
1022 return false;
1023 }
1024
1025 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001026 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1027 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001028 !ExpectCache(ctx.get(), expected)) {
1029 return false;
1030 }
1031
1032 return true;
1033}
1034
David Benjaminde942382016-02-11 12:02:01 -05001035static uint16_t EpochFromSequence(uint64_t seq) {
1036 return static_cast<uint16_t>(seq >> 48);
1037}
1038
1039static ScopedX509 GetTestCertificate() {
1040 static const char kCertPEM[] =
1041 "-----BEGIN CERTIFICATE-----\n"
1042 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1043 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1044 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1045 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1046 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1047 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1048 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1049 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1050 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1051 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1052 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1053 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1054 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1055 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001056 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001057 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1058}
1059
1060static ScopedEVP_PKEY GetTestKey() {
1061 static const char kKeyPEM[] =
1062 "-----BEGIN RSA PRIVATE KEY-----\n"
1063 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1064 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1065 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1066 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1067 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1068 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1069 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1070 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1071 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1072 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1073 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1074 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1075 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1076 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001077 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001078 return ScopedEVP_PKEY(
1079 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1080}
1081
David Benjamin686bb192016-05-10 15:15:41 -04001082static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
1083 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1084 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001085 if (!client || !server) {
1086 return false;
1087 }
1088 SSL_set_connect_state(client.get());
1089 SSL_set_accept_state(server.get());
1090
1091 BIO *bio1, *bio2;
1092 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1093 return false;
1094 }
1095 // SSL_set_bio takes ownership.
1096 SSL_set_bio(client.get(), bio1, bio1);
1097 SSL_set_bio(server.get(), bio2, bio2);
1098
1099 // Drive both their handshakes to completion.
1100 for (;;) {
1101 int client_ret = SSL_do_handshake(client.get());
1102 int client_err = SSL_get_error(client.get(), client_ret);
1103 if (client_err != SSL_ERROR_NONE &&
1104 client_err != SSL_ERROR_WANT_READ &&
1105 client_err != SSL_ERROR_WANT_WRITE) {
1106 fprintf(stderr, "Client error: %d\n", client_err);
1107 return false;
1108 }
1109
1110 int server_ret = SSL_do_handshake(server.get());
1111 int server_err = SSL_get_error(server.get(), server_ret);
1112 if (server_err != SSL_ERROR_NONE &&
1113 server_err != SSL_ERROR_WANT_READ &&
1114 server_err != SSL_ERROR_WANT_WRITE) {
1115 fprintf(stderr, "Server error: %d\n", server_err);
1116 return false;
1117 }
1118
1119 if (client_ret == 1 && server_ret == 1) {
1120 break;
1121 }
1122 }
1123
David Benjamin686bb192016-05-10 15:15:41 -04001124 *out_client = std::move(client);
1125 *out_server = std::move(server);
1126 return true;
1127}
1128
1129static bool TestSequenceNumber(bool dtls) {
1130 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1131 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1132 if (!client_ctx || !server_ctx) {
1133 return false;
1134 }
1135
1136 ScopedX509 cert = GetTestCertificate();
1137 ScopedEVP_PKEY key = GetTestKey();
1138 if (!cert || !key ||
1139 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1140 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1141 return false;
1142 }
1143
1144 ScopedSSL client, server;
1145 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1146 server_ctx.get())) {
1147 return false;
1148 }
1149
David Benjaminde942382016-02-11 12:02:01 -05001150 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1151 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1152 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1153 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1154
1155 if (dtls) {
1156 // Both client and server must be at epoch 1.
1157 if (EpochFromSequence(client_read_seq) != 1 ||
1158 EpochFromSequence(client_write_seq) != 1 ||
1159 EpochFromSequence(server_read_seq) != 1 ||
1160 EpochFromSequence(server_write_seq) != 1) {
1161 fprintf(stderr, "Bad epochs.\n");
1162 return false;
1163 }
1164
1165 // The next record to be written should exceed the largest received.
1166 if (client_write_seq <= server_read_seq ||
1167 server_write_seq <= client_read_seq) {
1168 fprintf(stderr, "Inconsistent sequence numbers.\n");
1169 return false;
1170 }
1171 } else {
1172 // The next record to be written should equal the next to be received.
1173 if (client_write_seq != server_read_seq ||
1174 server_write_seq != client_write_seq) {
1175 fprintf(stderr, "Inconsistent sequence numbers.\n");
1176 return false;
1177 }
1178 }
1179
1180 // Send a record from client to server.
1181 uint8_t byte = 0;
1182 if (SSL_write(client.get(), &byte, 1) != 1 ||
1183 SSL_read(server.get(), &byte, 1) != 1) {
1184 fprintf(stderr, "Could not send byte.\n");
1185 return false;
1186 }
1187
1188 // The client write and server read sequence numbers should have incremented.
1189 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1190 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1191 fprintf(stderr, "Sequence numbers did not increment.\n");\
1192 return false;
1193 }
1194
1195 return true;
1196}
1197
David Benjamin686bb192016-05-10 15:15:41 -04001198static bool TestOneSidedShutdown() {
1199 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1200 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1201 if (!client_ctx || !server_ctx) {
1202 return false;
1203 }
1204
1205 ScopedX509 cert = GetTestCertificate();
1206 ScopedEVP_PKEY key = GetTestKey();
1207 if (!cert || !key ||
1208 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1209 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1210 return false;
1211 }
1212
1213 ScopedSSL client, server;
1214 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1215 server_ctx.get())) {
1216 return false;
1217 }
1218
1219 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1220 // one side has shut down.
1221 if (SSL_shutdown(client.get()) != 0) {
1222 fprintf(stderr, "Could not shutdown.\n");
1223 return false;
1224 }
1225
1226 // Reading from the server should consume the EOF.
1227 uint8_t byte;
1228 if (SSL_read(server.get(), &byte, 1) != 0 ||
1229 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1230 fprintf(stderr, "Connection was not shut down cleanly.\n");
1231 return false;
1232 }
1233
1234 // However, the server may continue to write data and then shut down the
1235 // connection.
1236 byte = 42;
1237 if (SSL_write(server.get(), &byte, 1) != 1 ||
1238 SSL_read(client.get(), &byte, 1) != 1 ||
1239 byte != 42) {
1240 fprintf(stderr, "Could not send byte.\n");
1241 return false;
1242 }
1243
1244 // The server may then shutdown the connection.
1245 if (SSL_shutdown(server.get()) != 1 ||
1246 SSL_shutdown(client.get()) != 1) {
1247 fprintf(stderr, "Could not complete shutdown.\n");
1248 return false;
1249 }
1250
1251 return true;
1252}
1253
David Benjamin1d128f32015-09-08 17:41:40 -04001254int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04001255 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04001256
David Benjamin1d77e562015-03-22 17:22:08 -04001257 if (!TestCipherRules() ||
1258 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
1259 !TestSSL_SESSIONEncoding(kCustomSession) ||
David Benjamin26416e92015-08-22 16:04:17 -04001260 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
David Benjaminf297e022015-05-28 19:55:29 -04001261 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
David Benjamin338e0672015-05-28 20:00:08 -04001262 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
David Benjaminfd67aa82015-06-15 19:41:48 -04001263 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin1d77e562015-03-22 17:22:08 -04001264 !TestDefaultVersion(0, &TLS_method) ||
1265 !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
1266 !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
1267 !TestDefaultVersion(TLS1_1_VERSION, &TLSv1_1_method) ||
David Benjamin68793732015-05-04 20:20:48 -04001268 !TestDefaultVersion(TLS1_2_VERSION, &TLSv1_2_method) ||
David Benjamin1d77e562015-03-22 17:22:08 -04001269 !TestDefaultVersion(0, &DTLS_method) ||
1270 !TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
1271 !TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
David Benjamin422fe082015-07-21 22:03:43 -04001272 !TestCipherGetRFCName() ||
David Benjamin1d128f32015-09-08 17:41:40 -04001273 !TestPaddingExtension() ||
David Benjamin0f653952015-10-18 14:28:01 -04001274 !TestClientCAList() ||
David Benjaminde942382016-02-11 12:02:01 -05001275 !TestInternalSessionCache() ||
1276 !TestSequenceNumber(false /* TLS */) ||
David Benjamin686bb192016-05-10 15:15:41 -04001277 !TestSequenceNumber(true /* DTLS */) ||
1278 !TestOneSidedShutdown()) {
Brian Smith83a82982015-04-09 16:21:10 -10001279 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04001280 return 1;
1281 }
1282
David Benjamin2e521212014-07-16 14:37:51 -04001283 printf("PASS\n");
1284 return 0;
1285}