blob: 0dc0884b2f85ce816c1443e6b4778ab60f27086b [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040026#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040027#include <openssl/err.h>
David Benjaminde942382016-02-11 12:02:01 -050028#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040029#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050031#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032
Steven Valdez87eab492016-06-27 16:34:59 -040033#include "internal.h"
Adam Langleyd2b5af52016-07-12 08:03:59 -070034#include "test/scoped_types.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020035#include "../crypto/test/test_util.h"
36
David Benjamin1d77e562015-03-22 17:22:08 -040037
38struct ExpectedCipher {
39 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040040 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040041};
David Benjaminbb0a17c2014-09-20 15:35:39 -040042
David Benjamin1d77e562015-03-22 17:22:08 -040043struct CipherTest {
44 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040045 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050046 // The list of expected ciphers, in order.
47 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040048};
David Benjaminbb0a17c2014-09-20 15:35:39 -040049
David Benjaminfb974e62015-12-16 19:34:22 -050050static const CipherTest kCipherTests[] = {
51 // Selecting individual ciphers should work.
52 {
53 "ECDHE-ECDSA-CHACHA20-POLY1305:"
54 "ECDHE-RSA-CHACHA20-POLY1305:"
55 "ECDHE-ECDSA-AES128-GCM-SHA256:"
56 "ECDHE-RSA-AES128-GCM-SHA256",
57 {
58 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
59 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
60 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
61 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
62 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
63 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
64 },
65 },
66 // + reorders selected ciphers to the end, keeping their relative order.
67 {
68 "ECDHE-ECDSA-CHACHA20-POLY1305:"
69 "ECDHE-RSA-CHACHA20-POLY1305:"
70 "ECDHE-ECDSA-AES128-GCM-SHA256:"
71 "ECDHE-RSA-AES128-GCM-SHA256:"
72 "+aRSA",
73 {
74 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
75 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
76 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
77 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
78 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
80 },
81 },
82 // ! banishes ciphers from future selections.
83 {
84 "!aRSA:"
85 "ECDHE-ECDSA-CHACHA20-POLY1305:"
86 "ECDHE-RSA-CHACHA20-POLY1305:"
87 "ECDHE-ECDSA-AES128-GCM-SHA256:"
88 "ECDHE-RSA-AES128-GCM-SHA256",
89 {
90 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
91 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
92 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 },
94 },
95 // Multiple masks can be ANDed in a single rule.
96 {
97 "kRSA+AESGCM+AES128",
98 {
99 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
100 },
101 },
102 // - removes selected ciphers, but preserves their order for future
103 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
104 // ECDHE_RSA.
105 {
106 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
107 "AESGCM+AES128+aRSA",
108 {
109 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
110 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
111 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
112 },
113 },
114 // Unknown selectors are no-ops.
115 {
116 "ECDHE-ECDSA-CHACHA20-POLY1305:"
117 "ECDHE-RSA-CHACHA20-POLY1305:"
118 "ECDHE-ECDSA-AES128-GCM-SHA256:"
119 "ECDHE-RSA-AES128-GCM-SHA256:"
120 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
121 {
122 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
123 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
124 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
125 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
126 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Square brackets specify equi-preference groups.
131 {
132 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
133 "[ECDHE-RSA-CHACHA20-POLY1305]:"
134 "ECDHE-RSA-AES128-GCM-SHA256",
135 {
136 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
137 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
138 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
139 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
140 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
141 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
142 },
143 },
144 // @STRENGTH performs a stable strength-sort of the selected ciphers and
145 // only the selected ciphers.
146 {
147 // To simplify things, banish all but {ECDHE_RSA,RSA} x
148 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
149 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
150 // Order some ciphers backwards by strength.
151 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
152 // Select ECDHE ones and sort them by strength. Ties should resolve
153 // based on the order above.
154 "kECDHE:@STRENGTH:-ALL:"
155 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
156 // by strength. Then RSA, backwards by strength.
157 "aRSA",
158 {
159 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
160 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
161 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
162 {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
163 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
164 {SSL3_CK_RSA_RC4_128_SHA, 0},
165 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
166 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
167 },
168 },
169 // Exact ciphers may not be used in multi-part rules; they are treated
170 // as unknown aliases.
171 {
172 "ECDHE-ECDSA-AES128-GCM-SHA256:"
173 "ECDHE-RSA-AES128-GCM-SHA256:"
174 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
175 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
176 {
177 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
179 },
180 },
181 // SSLv3 matches everything that existed before TLS 1.2.
182 {
183 "AES128-SHA:AES128-SHA256:!SSLv3",
184 {
185 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
186 },
187 },
188 // TLSv1.2 matches everything added in TLS 1.2.
189 {
190 "AES128-SHA:AES128-SHA256:!TLSv1.2",
191 {
192 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
193 },
194 },
195 // The two directives have no intersection.
196 {
197 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
200 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
201 },
202 },
203 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
204 // name and not an alias. It may not be used in a multipart rule. (That the
205 // shared name works is covered by the standard tests.)
206 {
207 "ECDHE-ECDSA-CHACHA20-POLY1305:"
208 "ECDHE-RSA-CHACHA20-POLY1305:"
209 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
210 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
211 {
212 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
213 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
214 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
215 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
216 },
217 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400218};
219
220static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400221 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400222 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
223 "RSA]",
224 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400225 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400226 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400227 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400228 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400229 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400230 "",
231 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400232 // COMPLEMENTOFDEFAULT is empty.
233 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400234 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400236 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400237 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
238 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
239 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
240 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400241};
242
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700243static const char *kMustNotIncludeNull[] = {
244 "ALL",
245 "DEFAULT",
246 "ALL:!eNULL",
247 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500248 "MEDIUM",
249 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700250 "FIPS",
251 "SHA",
252 "SHA1",
253 "RSA",
254 "SSLv3",
255 "TLSv1",
256 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700257};
258
Matt Braithwaite053931e2016-05-25 12:06:05 -0700259static const char *kMustNotIncludeCECPQ1[] = {
260 "ALL",
261 "DEFAULT",
262 "MEDIUM",
263 "HIGH",
264 "FIPS",
265 "SHA",
266 "SHA1",
267 "SHA256",
268 "SHA384",
269 "RSA",
270 "SSLv3",
271 "TLSv1",
272 "TLSv1.2",
273 "aRSA",
274 "RSA",
275 "aECDSA",
276 "ECDSA",
277 "AES",
278 "AES128",
279 "AES256",
280 "AESGCM",
281 "CHACHA20",
282};
283
David Benjamin1d77e562015-03-22 17:22:08 -0400284static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
285 bool in_group = false;
286 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400287 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
288 if (!in_group && list->in_group_flags[i]) {
289 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400290 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400291 }
292 fprintf(stderr, "\t");
293 if (in_group) {
294 fprintf(stderr, " ");
295 }
296 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
297 if (in_group && !list->in_group_flags[i]) {
298 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400299 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400300 }
301 }
302}
303
David Benjaminfb974e62015-12-16 19:34:22 -0500304static bool TestCipherRule(const CipherTest &t) {
David Benjamin1d77e562015-03-22 17:22:08 -0400305 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
306 if (!ctx) {
307 return false;
David Benjamin65226252015-02-05 16:49:47 -0500308 }
309
David Benjaminfb974e62015-12-16 19:34:22 -0500310 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
311 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400312 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400313 }
314
David Benjamin1d77e562015-03-22 17:22:08 -0400315 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500316 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
317 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
318 PrintCipherPreferenceList(ctx->cipher_list);
319 return false;
320 }
321
322 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400323 const SSL_CIPHER *cipher =
324 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500325 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
326 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
327 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400328 PrintCipherPreferenceList(ctx->cipher_list);
329 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 }
331 }
332
David Benjamin1d77e562015-03-22 17:22:08 -0400333 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400334}
335
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700336static bool TestRuleDoesNotIncludeNull(const char *rule) {
337 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
338 if (!ctx) {
339 return false;
340 }
341 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
342 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
343 return false;
344 }
345 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
346 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
347 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
348 return false;
349 }
350 }
351 return true;
352}
353
Matt Braithwaite053931e2016-05-25 12:06:05 -0700354static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
355 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
356 if (!ctx) {
357 return false;
358 }
359 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
360 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
361 return false;
362 }
363 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
364 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
365 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
366 return false;
367 }
368 }
369 return true;
370}
371
David Benjamin1d77e562015-03-22 17:22:08 -0400372static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500373 for (const CipherTest &test : kCipherTests) {
374 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400375 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400376 }
377 }
378
David Benjaminfb974e62015-12-16 19:34:22 -0500379 for (const char *rule : kBadRules) {
David Benjamin1d77e562015-03-22 17:22:08 -0400380 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
381 if (!ctx) {
382 return false;
David Benjamin65226252015-02-05 16:49:47 -0500383 }
David Benjaminfb974e62015-12-16 19:34:22 -0500384 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
385 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400386 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400387 }
388 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400389 }
390
David Benjaminfb974e62015-12-16 19:34:22 -0500391 for (const char *rule : kMustNotIncludeNull) {
392 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700393 return false;
394 }
395 }
396
Matt Braithwaite053931e2016-05-25 12:06:05 -0700397 for (const char *rule : kMustNotIncludeCECPQ1) {
398 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
399 return false;
400 }
401 }
402
David Benjamin1d77e562015-03-22 17:22:08 -0400403 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400404}
David Benjamin2e521212014-07-16 14:37:51 -0400405
Adam Langley10f97f32016-07-12 08:09:33 -0700406// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
407// s_client -sess_out.
408static const char kOpenSSLSession[] =
409 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
410 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
411 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
412 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
413 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
414 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
415 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
416 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
417 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
418 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
419 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
420 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
421 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
422 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
423 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
424 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
425 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
426 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
427 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
428 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
429 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
430 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
431 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
432 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
433 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
434 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
435 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
436 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
437 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
438 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
439 "i4gv7Y5oliyn";
440
441// kCustomSession is a custom serialized SSL_SESSION generated by
442// filling in missing fields from |kOpenSSLSession|. This includes
443// providing |peer_sha256|, so |peer| is not serialized.
444static const char kCustomSession[] =
445 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
446 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
447 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
448 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
449 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
450 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
451 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
452 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
453
454// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
455static const char kBoringSSLSession[] =
456 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
457 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
458 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
459 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
460 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
461 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
462 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
463 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
464 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
465 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
466 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
467 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
468 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
469 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
470 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
471 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
472 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
473 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
474 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
475 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
476 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
477 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
478 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
479 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
480 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
481 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
482 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
483 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
484 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
485 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
486 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
487 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
488 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
489 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
490 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
491 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
492 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
493 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
494 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
495 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
496 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
497 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
498 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
499 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
500 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
501 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
502 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
503 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
504 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
505 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
506 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
507 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
508 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
509 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
510 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
511 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
512 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
513 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
514 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
515 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
516 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
517 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
518 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
519 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
520 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
521 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
522 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
523 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
524 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
525 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
526 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
527 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
528 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
529 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
530 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
531 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
532 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
533 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
534 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
535 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
536 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
537 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
538 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
539 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
540 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
541 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
542 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
543 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
544 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
545 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
546 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
547 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
548 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
549 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
550 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
551
552// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
553// the final (optional) element of |kCustomSession| with tag number 30.
554static const char kBadSessionExtraField[] =
555 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
556 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
557 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
558 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
559 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
560 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
561 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
562 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
563
564// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
565// the version of |kCustomSession| with 2.
566static const char kBadSessionVersion[] =
567 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
568 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
569 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
570 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
571 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
572 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
573 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
574 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
575
576// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
577// appended.
578static const char kBadSessionTrailingData[] =
579 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
580 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
581 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
582 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
583 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
584 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
585 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
586 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
587
David Benjamin1d77e562015-03-22 17:22:08 -0400588static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400589 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400590 if (!EVP_DecodedLength(&len, strlen(in))) {
591 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400592 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400593 }
594
David Benjamin1d77e562015-03-22 17:22:08 -0400595 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800596 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400597 strlen(in))) {
598 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400599 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400600 }
David Benjamin1d77e562015-03-22 17:22:08 -0400601 out->resize(len);
602 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400603}
604
David Benjamin1d77e562015-03-22 17:22:08 -0400605static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400606 const uint8_t *cptr;
607 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400608
David Benjamin1d77e562015-03-22 17:22:08 -0400609 // Decode the input.
610 std::vector<uint8_t> input;
611 if (!DecodeBase64(&input, input_b64)) {
612 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400613 }
614
David Benjamin1d77e562015-03-22 17:22:08 -0400615 // Verify the SSL_SESSION decodes.
David Benjaminef14b2d2015-11-11 14:01:27 -0800616 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400617 if (!session) {
618 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400619 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400620 }
621
David Benjamin1d77e562015-03-22 17:22:08 -0400622 // Verify the SSL_SESSION encoding round-trips.
623 size_t encoded_len;
Adam Langley10f97f32016-07-12 08:09:33 -0700624 ScopedOpenSSLBytes encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400625 uint8_t *encoded_raw;
626 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400627 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400628 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400629 }
David Benjamin1d77e562015-03-22 17:22:08 -0400630 encoded.reset(encoded_raw);
631 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800632 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400633 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200634 hexdump(stderr, "Before: ", input.data(), input.size());
635 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400636 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400637 }
David Benjamin3cac4502014-10-21 01:46:30 -0400638
David Benjaminfd67aa82015-06-15 19:41:48 -0400639 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800640 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400641 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800642 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400643 fprintf(stderr, "d2i_SSL_SESSION failed\n");
644 return false;
645 }
646
David Benjamin1d77e562015-03-22 17:22:08 -0400647 // Verify the SSL_SESSION encoding round-trips via the legacy API.
648 int len = i2d_SSL_SESSION(session.get(), NULL);
649 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400650 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400651 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400652 }
653
David Benjamin1d77e562015-03-22 17:22:08 -0400654 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
655 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400656 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400657 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400658 }
David Benjamin1d77e562015-03-22 17:22:08 -0400659
660 ptr = encoded.get();
661 len = i2d_SSL_SESSION(session.get(), &ptr);
662 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400663 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400664 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400665 }
David Benjamin1d77e562015-03-22 17:22:08 -0400666 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400667 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400668 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400669 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800670 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400671 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400672 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400673 }
674
David Benjamin1d77e562015-03-22 17:22:08 -0400675 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400676}
677
David Benjaminf297e022015-05-28 19:55:29 -0400678static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
679 std::vector<uint8_t> input;
680 if (!DecodeBase64(&input, input_b64)) {
681 return false;
682 }
683
684 // Verify that the SSL_SESSION fails to decode.
David Benjaminef14b2d2015-11-11 14:01:27 -0800685 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400686 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400687 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400688 return false;
689 }
690 ERR_clear_error();
691 return true;
692}
693
David Benjamin10e664b2016-06-20 22:20:47 -0400694static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400695 const SSL_METHOD *(*method)(void)) {
696 ScopedSSL_CTX ctx(SSL_CTX_new(method()));
697 if (!ctx) {
698 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500699 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400700 if (ctx->min_version != min_version || ctx->max_version != max_version) {
701 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
702 ctx->min_version, ctx->max_version, min_version, max_version);
703 return false;
704 }
705 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500706}
707
David Benjamin1d77e562015-03-22 17:22:08 -0400708static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500709 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
710 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400711 return false;
David Benjamin65226252015-02-05 16:49:47 -0500712 }
Adam Langley10f97f32016-07-12 08:09:33 -0700713 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400714 if (!rfc_name) {
715 return false;
716 }
David Benjamin67be0482015-04-20 16:19:00 -0400717 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400718 return true;
David Benjamin65226252015-02-05 16:49:47 -0500719}
720
721typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500722 int id;
David Benjamin65226252015-02-05 16:49:47 -0500723 const char *rfc_name;
724} CIPHER_RFC_NAME_TEST;
725
726static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500727 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
728 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
729 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500730 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
731 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
732 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500733 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
734 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
735 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
736 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
737 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
738 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
739 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
740 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
741 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
742 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
743 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Adam Langley85bc5602015-06-09 09:54:04 -0700744 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
745 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500746 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
747 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400748 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000749 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500750 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000751 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500752 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500753};
754
David Benjamin1d77e562015-03-22 17:22:08 -0400755static bool TestCipherGetRFCName(void) {
756 for (size_t i = 0;
757 i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500758 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400759 std::string rfc_name;
760 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
761 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
762 return false;
David Benjamin65226252015-02-05 16:49:47 -0500763 }
David Benjamin1d77e562015-03-22 17:22:08 -0400764 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500765 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400766 rfc_name.c_str(), test->rfc_name);
767 return false;
David Benjamin65226252015-02-05 16:49:47 -0500768 }
David Benjamin65226252015-02-05 16:49:47 -0500769 }
David Benjamin1d77e562015-03-22 17:22:08 -0400770 return true;
David Benjamin65226252015-02-05 16:49:47 -0500771}
772
David Benjamin422fe082015-07-21 22:03:43 -0400773// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
774// replaced for one of length |ticket_len| or nullptr on failure.
775static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
776 std::vector<uint8_t> der;
777 if (!DecodeBase64(&der, kOpenSSLSession)) {
778 return nullptr;
779 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800780 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400781 if (!session) {
782 return nullptr;
783 }
784
785 // Swap out the ticket for a garbage one.
786 OPENSSL_free(session->tlsext_tick);
787 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
788 if (session->tlsext_tick == nullptr) {
789 return nullptr;
790 }
791 memset(session->tlsext_tick, 'a', ticket_len);
792 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400793
794 // Fix up the timeout.
795 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400796 return session;
797}
798
David Benjaminafc64de2016-07-19 17:12:41 +0200799static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
800 ScopedBIO bio(BIO_new(BIO_s_mem()));
801 if (!bio) {
802 return false;
803 }
804 // Do not configure a reading BIO, but record what's written to a memory BIO.
805 SSL_set_bio(ssl, nullptr /* rbio */, BIO_up_ref(bio.get()));
806 int ret = SSL_connect(ssl);
807 if (ret > 0) {
808 // SSL_connect should fail without a BIO to write to.
809 return false;
810 }
811 ERR_clear_error();
812
813 const uint8_t *client_hello;
814 size_t client_hello_len;
815 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
816 return false;
817 }
818 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
819 return true;
820}
821
David Benjamin422fe082015-07-21 22:03:43 -0400822// GetClientHelloLen creates a client SSL connection with a ticket of length
823// |ticket_len| and records the ClientHello. It returns the length of the
824// ClientHello, not including the record header, on success and zero on error.
825static size_t GetClientHelloLen(size_t ticket_len) {
826 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
827 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
828 if (!ctx || !session) {
829 return 0;
830 }
831 ScopedSSL ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200832 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400833 return 0;
834 }
David Benjaminafc64de2016-07-19 17:12:41 +0200835 std::vector<uint8_t> client_hello;
836 if (!GetClientHello(ssl.get(), &client_hello) ||
837 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400838 return 0;
839 }
David Benjaminafc64de2016-07-19 17:12:41 +0200840 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400841}
842
843struct PaddingTest {
844 size_t input_len, padded_len;
845};
846
847static const PaddingTest kPaddingTests[] = {
848 // ClientHellos of length below 0x100 do not require padding.
849 {0xfe, 0xfe},
850 {0xff, 0xff},
851 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
852 {0x100, 0x200},
853 {0x123, 0x200},
854 {0x1fb, 0x200},
855 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
856 // padding extension takes a minimum of four bytes plus one required content
857 // byte. (To work around yet more server bugs, we avoid empty final
858 // extensions.)
859 {0x1fc, 0x201},
860 {0x1fd, 0x202},
861 {0x1fe, 0x203},
862 {0x1ff, 0x204},
863 // Finally, larger ClientHellos need no padding.
864 {0x200, 0x200},
865 {0x201, 0x201},
866};
867
868static bool TestPaddingExtension() {
869 // Sample a baseline length.
870 size_t base_len = GetClientHelloLen(1);
871 if (base_len == 0) {
872 return false;
873 }
874
875 for (const PaddingTest &test : kPaddingTests) {
876 if (base_len > test.input_len) {
877 fprintf(stderr, "Baseline ClientHello too long.\n");
878 return false;
879 }
880
881 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
882 if (padded_len != test.padded_len) {
883 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
884 static_cast<unsigned>(test.input_len),
885 static_cast<unsigned>(padded_len),
886 static_cast<unsigned>(test.padded_len));
887 return false;
888 }
889 }
890 return true;
891}
892
David Benjamin1d128f32015-09-08 17:41:40 -0400893// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
894// before configuring as a server.
895static bool TestClientCAList() {
896 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
897 if (!ctx) {
898 return false;
899 }
900 ScopedSSL ssl(SSL_new(ctx.get()));
901 if (!ssl) {
902 return false;
903 }
904
905 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
906 if (stack == nullptr) {
907 return false;
908 }
909 // |SSL_set_client_CA_list| takes ownership.
910 SSL_set_client_CA_list(ssl.get(), stack);
911
912 return SSL_get_client_CA_list(ssl.get()) == stack;
913}
914
David Benjamin0f653952015-10-18 14:28:01 -0400915static void AppendSession(SSL_SESSION *session, void *arg) {
916 std::vector<SSL_SESSION*> *out =
917 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
918 out->push_back(session);
919}
920
921// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
922// order.
923static bool ExpectCache(SSL_CTX *ctx,
924 const std::vector<SSL_SESSION*> &expected) {
925 // Check the linked list.
926 SSL_SESSION *ptr = ctx->session_cache_head;
927 for (SSL_SESSION *session : expected) {
928 if (ptr != session) {
929 return false;
930 }
931 // TODO(davidben): This is an absurd way to denote the end of the list.
932 if (ptr->next ==
933 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
934 ptr = nullptr;
935 } else {
936 ptr = ptr->next;
937 }
938 }
939 if (ptr != nullptr) {
940 return false;
941 }
942
943 // Check the hash table.
944 std::vector<SSL_SESSION*> actual, expected_copy;
945 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
946 expected_copy = expected;
947
948 std::sort(actual.begin(), actual.end());
949 std::sort(expected_copy.begin(), expected_copy.end());
950
951 return actual == expected_copy;
952}
953
954static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
955 ScopedSSL_SESSION ret(SSL_SESSION_new());
956 if (!ret) {
957 return nullptr;
958 }
959
960 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
961 memset(ret->session_id, 0, ret->session_id_length);
962 memcpy(ret->session_id, &number, sizeof(number));
963 return ret;
964}
965
David Benjamin0f653952015-10-18 14:28:01 -0400966// Test that the internal session cache behaves as expected.
967static bool TestInternalSessionCache() {
968 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
969 if (!ctx) {
970 return false;
971 }
972
973 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500974 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400975 for (int i = 0; i < 10; i++) {
976 ScopedSSL_SESSION session = CreateTestSession(i);
977 if (!session) {
978 return false;
979 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500980 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400981 }
982
983 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
984
985 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500986 for (const auto &session : sessions) {
987 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400988 return false;
989 }
990 }
991
992 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500993 std::vector<SSL_SESSION*> expected = {
994 sessions[9].get(),
995 sessions[8].get(),
996 sessions[7].get(),
997 sessions[6].get(),
998 sessions[5].get(),
999 };
David Benjamin0f653952015-10-18 14:28:01 -04001000 if (!ExpectCache(ctx.get(), expected)) {
1001 return false;
1002 }
1003
1004 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001005 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001006 !ExpectCache(ctx.get(), expected)) {
1007 return false;
1008 }
1009
1010 // Although collisions should be impossible (256-bit session IDs), the cache
1011 // must handle them gracefully.
1012 ScopedSSL_SESSION collision(CreateTestSession(7));
1013 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1014 return false;
1015 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001016 expected = {
1017 collision.get(),
1018 sessions[9].get(),
1019 sessions[8].get(),
1020 sessions[6].get(),
1021 sessions[5].get(),
1022 };
David Benjamin0f653952015-10-18 14:28:01 -04001023 if (!ExpectCache(ctx.get(), expected)) {
1024 return false;
1025 }
1026
1027 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001028 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001029 return false;
1030 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001031 expected = {
1032 collision.get(),
1033 sessions[9].get(),
1034 sessions[8].get(),
1035 sessions[5].get(),
1036 };
David Benjamin0f653952015-10-18 14:28:01 -04001037 if (!ExpectCache(ctx.get(), expected)) {
1038 return false;
1039 }
1040
1041 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001042 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1043 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001044 !ExpectCache(ctx.get(), expected)) {
1045 return false;
1046 }
1047
1048 return true;
1049}
1050
David Benjaminde942382016-02-11 12:02:01 -05001051static uint16_t EpochFromSequence(uint64_t seq) {
1052 return static_cast<uint16_t>(seq >> 48);
1053}
1054
1055static ScopedX509 GetTestCertificate() {
1056 static const char kCertPEM[] =
1057 "-----BEGIN CERTIFICATE-----\n"
1058 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1059 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1060 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1061 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1062 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1063 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1064 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1065 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1066 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1067 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1068 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1069 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1070 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1071 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001072 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001073 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1074}
1075
1076static ScopedEVP_PKEY GetTestKey() {
1077 static const char kKeyPEM[] =
1078 "-----BEGIN RSA PRIVATE KEY-----\n"
1079 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1080 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1081 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1082 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1083 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1084 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1085 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1086 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1087 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1088 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1089 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1090 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1091 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1092 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001093 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001094 return ScopedEVP_PKEY(
1095 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1096}
1097
David Benjamin686bb192016-05-10 15:15:41 -04001098static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
1099 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1100 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001101 if (!client || !server) {
1102 return false;
1103 }
1104 SSL_set_connect_state(client.get());
1105 SSL_set_accept_state(server.get());
1106
1107 BIO *bio1, *bio2;
1108 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1109 return false;
1110 }
1111 // SSL_set_bio takes ownership.
1112 SSL_set_bio(client.get(), bio1, bio1);
1113 SSL_set_bio(server.get(), bio2, bio2);
1114
1115 // Drive both their handshakes to completion.
1116 for (;;) {
1117 int client_ret = SSL_do_handshake(client.get());
1118 int client_err = SSL_get_error(client.get(), client_ret);
1119 if (client_err != SSL_ERROR_NONE &&
1120 client_err != SSL_ERROR_WANT_READ &&
1121 client_err != SSL_ERROR_WANT_WRITE) {
1122 fprintf(stderr, "Client error: %d\n", client_err);
1123 return false;
1124 }
1125
1126 int server_ret = SSL_do_handshake(server.get());
1127 int server_err = SSL_get_error(server.get(), server_ret);
1128 if (server_err != SSL_ERROR_NONE &&
1129 server_err != SSL_ERROR_WANT_READ &&
1130 server_err != SSL_ERROR_WANT_WRITE) {
1131 fprintf(stderr, "Server error: %d\n", server_err);
1132 return false;
1133 }
1134
1135 if (client_ret == 1 && server_ret == 1) {
1136 break;
1137 }
1138 }
1139
David Benjamin686bb192016-05-10 15:15:41 -04001140 *out_client = std::move(client);
1141 *out_server = std::move(server);
1142 return true;
1143}
1144
1145static bool TestSequenceNumber(bool dtls) {
1146 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1147 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1148 if (!client_ctx || !server_ctx) {
1149 return false;
1150 }
1151
1152 ScopedX509 cert = GetTestCertificate();
1153 ScopedEVP_PKEY key = GetTestKey();
1154 if (!cert || !key ||
1155 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1156 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1157 return false;
1158 }
1159
1160 ScopedSSL client, server;
1161 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1162 server_ctx.get())) {
1163 return false;
1164 }
1165
David Benjaminde942382016-02-11 12:02:01 -05001166 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1167 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1168 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1169 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1170
1171 if (dtls) {
1172 // Both client and server must be at epoch 1.
1173 if (EpochFromSequence(client_read_seq) != 1 ||
1174 EpochFromSequence(client_write_seq) != 1 ||
1175 EpochFromSequence(server_read_seq) != 1 ||
1176 EpochFromSequence(server_write_seq) != 1) {
1177 fprintf(stderr, "Bad epochs.\n");
1178 return false;
1179 }
1180
1181 // The next record to be written should exceed the largest received.
1182 if (client_write_seq <= server_read_seq ||
1183 server_write_seq <= client_read_seq) {
1184 fprintf(stderr, "Inconsistent sequence numbers.\n");
1185 return false;
1186 }
1187 } else {
1188 // The next record to be written should equal the next to be received.
1189 if (client_write_seq != server_read_seq ||
1190 server_write_seq != client_write_seq) {
1191 fprintf(stderr, "Inconsistent sequence numbers.\n");
1192 return false;
1193 }
1194 }
1195
1196 // Send a record from client to server.
1197 uint8_t byte = 0;
1198 if (SSL_write(client.get(), &byte, 1) != 1 ||
1199 SSL_read(server.get(), &byte, 1) != 1) {
1200 fprintf(stderr, "Could not send byte.\n");
1201 return false;
1202 }
1203
1204 // The client write and server read sequence numbers should have incremented.
1205 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1206 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1207 fprintf(stderr, "Sequence numbers did not increment.\n");\
1208 return false;
1209 }
1210
1211 return true;
1212}
1213
David Benjamin686bb192016-05-10 15:15:41 -04001214static bool TestOneSidedShutdown() {
1215 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1216 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1217 if (!client_ctx || !server_ctx) {
1218 return false;
1219 }
1220
1221 ScopedX509 cert = GetTestCertificate();
1222 ScopedEVP_PKEY key = GetTestKey();
1223 if (!cert || !key ||
1224 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1225 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1226 return false;
1227 }
1228
1229 ScopedSSL client, server;
1230 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1231 server_ctx.get())) {
1232 return false;
1233 }
1234
1235 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1236 // one side has shut down.
1237 if (SSL_shutdown(client.get()) != 0) {
1238 fprintf(stderr, "Could not shutdown.\n");
1239 return false;
1240 }
1241
1242 // Reading from the server should consume the EOF.
1243 uint8_t byte;
1244 if (SSL_read(server.get(), &byte, 1) != 0 ||
1245 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1246 fprintf(stderr, "Connection was not shut down cleanly.\n");
1247 return false;
1248 }
1249
1250 // However, the server may continue to write data and then shut down the
1251 // connection.
1252 byte = 42;
1253 if (SSL_write(server.get(), &byte, 1) != 1 ||
1254 SSL_read(client.get(), &byte, 1) != 1 ||
1255 byte != 42) {
1256 fprintf(stderr, "Could not send byte.\n");
1257 return false;
1258 }
1259
1260 // The server may then shutdown the connection.
1261 if (SSL_shutdown(server.get()) != 1 ||
1262 SSL_shutdown(client.get()) != 1) {
1263 fprintf(stderr, "Could not complete shutdown.\n");
1264 return false;
1265 }
1266
1267 return true;
1268}
Steven Valdez87eab492016-06-27 16:34:59 -04001269static bool TestSessionDuplication() {
1270 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1271 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1272 if (!client_ctx || !server_ctx) {
1273 return false;
1274 }
1275
1276 ScopedX509 cert = GetTestCertificate();
1277 ScopedEVP_PKEY key = GetTestKey();
1278 if (!cert || !key ||
1279 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1280 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1281 return false;
1282 }
1283
1284 ScopedSSL client, server;
1285 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1286 server_ctx.get())) {
1287 return false;
1288 }
1289
1290 SSL_SESSION *session0 = SSL_get_session(client.get());
1291 ScopedSSL_SESSION session1(SSL_SESSION_dup(session0, 1));
1292 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001293 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001294 }
David Benjamin4501bd52016-08-01 13:39:41 -04001295
Steven Valdez87eab492016-06-27 16:34:59 -04001296 uint8_t *s0_bytes, *s1_bytes;
1297 size_t s0_len, s1_len;
1298
1299 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1300 return false;
1301 }
1302 ScopedOpenSSLBytes free_s0(s0_bytes);
1303
1304 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1305 return false;
1306 }
1307 ScopedOpenSSLBytes free_s1(s1_bytes);
1308
1309 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1310}
David Benjamin686bb192016-05-10 15:15:41 -04001311
David Benjamin5c0fb882016-06-14 14:03:51 -04001312static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1313 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1314 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1315 SSL_get_wfd(ssl), rfd, wfd);
1316 return false;
1317 }
1318
1319 // The wrapper BIOs are always equal when fds are equal, even if set
1320 // individually.
1321 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1322 fprintf(stderr, "rbio and wbio did not match.\n");
1323 return false;
1324 }
1325
1326 return true;
1327}
1328
1329static bool TestSetFD() {
1330 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1331 if (!ctx) {
1332 return false;
1333 }
1334
1335 // Test setting different read and write FDs.
1336 ScopedSSL ssl(SSL_new(ctx.get()));
1337 if (!ssl ||
1338 !SSL_set_rfd(ssl.get(), 1) ||
1339 !SSL_set_wfd(ssl.get(), 2) ||
1340 !ExpectFDs(ssl.get(), 1, 2)) {
1341 return false;
1342 }
1343
1344 // Test setting the same FD.
1345 ssl.reset(SSL_new(ctx.get()));
1346 if (!ssl ||
1347 !SSL_set_fd(ssl.get(), 1) ||
1348 !ExpectFDs(ssl.get(), 1, 1)) {
1349 return false;
1350 }
1351
1352 // Test setting the same FD one side at a time.
1353 ssl.reset(SSL_new(ctx.get()));
1354 if (!ssl ||
1355 !SSL_set_rfd(ssl.get(), 1) ||
1356 !SSL_set_wfd(ssl.get(), 1) ||
1357 !ExpectFDs(ssl.get(), 1, 1)) {
1358 return false;
1359 }
1360
1361 // Test setting the same FD in the other order.
1362 ssl.reset(SSL_new(ctx.get()));
1363 if (!ssl ||
1364 !SSL_set_wfd(ssl.get(), 1) ||
1365 !SSL_set_rfd(ssl.get(), 1) ||
1366 !ExpectFDs(ssl.get(), 1, 1)) {
1367 return false;
1368 }
1369
David Benjamin5c0fb882016-06-14 14:03:51 -04001370 // Test changing the read FD partway through.
1371 ssl.reset(SSL_new(ctx.get()));
1372 if (!ssl ||
1373 !SSL_set_fd(ssl.get(), 1) ||
1374 !SSL_set_rfd(ssl.get(), 2) ||
1375 !ExpectFDs(ssl.get(), 2, 1)) {
1376 return false;
1377 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001378
1379 // Test changing the write FD partway through.
1380 ssl.reset(SSL_new(ctx.get()));
1381 if (!ssl ||
1382 !SSL_set_fd(ssl.get(), 1) ||
1383 !SSL_set_wfd(ssl.get(), 2) ||
1384 !ExpectFDs(ssl.get(), 1, 2)) {
1385 return false;
1386 }
1387
1388 // Test a no-op change to the read FD partway through.
1389 ssl.reset(SSL_new(ctx.get()));
1390 if (!ssl ||
1391 !SSL_set_fd(ssl.get(), 1) ||
1392 !SSL_set_rfd(ssl.get(), 1) ||
1393 !ExpectFDs(ssl.get(), 1, 1)) {
1394 return false;
1395 }
1396
1397 // Test a no-op change to the write FD partway through.
1398 ssl.reset(SSL_new(ctx.get()));
1399 if (!ssl ||
1400 !SSL_set_fd(ssl.get(), 1) ||
1401 !SSL_set_wfd(ssl.get(), 1) ||
1402 !ExpectFDs(ssl.get(), 1, 1)) {
1403 return false;
1404 }
1405
1406 // ASan builds will implicitly test that the internal |BIO| reference-counting
1407 // is correct.
1408
1409 return true;
1410}
1411
David Benjamin4501bd52016-08-01 13:39:41 -04001412static bool TestSetBIO() {
1413 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1414 if (!ctx) {
1415 return false;
1416 }
1417
1418 ScopedSSL ssl(SSL_new(ctx.get()));
1419 ScopedBIO bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
1420 bio3(BIO_new(BIO_s_mem()));
1421 if (!ssl || !bio1 || !bio2 || !bio3) {
1422 return false;
1423 }
1424
1425 // SSL_set_bio takes one reference when the parameters are the same.
1426 BIO_up_ref(bio1.get());
1427 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1428
1429 // Repeating the call does nothing.
1430 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1431
1432 // It takes one reference each when the parameters are different.
1433 BIO_up_ref(bio2.get());
1434 BIO_up_ref(bio3.get());
1435 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1436
1437 // Repeating the call does nothing.
1438 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1439
1440 // It takes one reference when changing only wbio.
1441 BIO_up_ref(bio1.get());
1442 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1443
1444 // It takes one reference when changing only rbio and the two are different.
1445 BIO_up_ref(bio3.get());
1446 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1447
1448 // If setting wbio to rbio, it takes no additional references.
1449 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1450
1451 // From there, wbio may be switched to something else.
1452 BIO_up_ref(bio1.get());
1453 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1454
1455 // If setting rbio to wbio, it takes no additional references.
1456 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1457
1458 // From there, rbio may be switched to something else, but, for historical
1459 // reasons, it takes a reference to both parameters.
1460 BIO_up_ref(bio1.get());
1461 BIO_up_ref(bio2.get());
1462 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1463
1464 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1465 // is correct.
1466 return true;
1467}
1468
David Benjamin25490f22016-07-14 00:22:54 -04001469static uint16_t kVersions[] = {
1470 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1471};
1472
1473static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1474
David Benjaminadd5e522016-07-14 00:33:24 -04001475static bool TestGetPeerCertificate() {
1476 ScopedX509 cert = GetTestCertificate();
1477 ScopedEVP_PKEY key = GetTestKey();
1478 if (!cert || !key) {
1479 return false;
1480 }
1481
1482 for (uint16_t version : kVersions) {
1483 // Configure both client and server to accept any certificate.
1484 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1485 if (!ctx ||
1486 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1487 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1488 return false;
1489 }
1490 SSL_CTX_set_min_version(ctx.get(), version);
1491 SSL_CTX_set_max_version(ctx.get(), version);
1492 SSL_CTX_set_verify(
1493 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1494 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1495
1496 ScopedSSL client, server;
1497 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get())) {
1498 return false;
1499 }
1500
1501 // Client and server should both see the leaf certificate.
1502 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1503 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1504 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1505 return false;
1506 }
1507
1508 peer.reset(SSL_get_peer_certificate(client.get()));
1509 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1510 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1511 return false;
1512 }
1513
1514 // However, for historical reasons, the chain includes the leaf on the
1515 // client, but does not on the server.
1516 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1517 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1518 return false;
1519 }
1520
1521 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1522 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1523 return false;
1524 }
1525 }
1526
1527 return true;
1528}
1529
David Benjamin25490f22016-07-14 00:22:54 -04001530static bool TestRetainOnlySHA256OfCerts() {
1531 ScopedX509 cert = GetTestCertificate();
1532 ScopedEVP_PKEY key = GetTestKey();
1533 if (!cert || !key) {
1534 return false;
1535 }
1536
1537 uint8_t *cert_der = NULL;
1538 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1539 if (cert_der_len < 0) {
1540 return false;
1541 }
1542 ScopedOpenSSLBytes free_cert_der(cert_der);
1543
1544 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1545 SHA256(cert_der, cert_der_len, cert_sha256);
1546
1547 for (uint16_t version : kVersions) {
1548 // Configure both client and server to accept any certificate, but the
1549 // server must retain only the SHA-256 of the peer.
1550 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1551 if (!ctx ||
1552 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1553 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1554 return false;
1555 }
1556 SSL_CTX_set_min_version(ctx.get(), version);
1557 SSL_CTX_set_max_version(ctx.get(), version);
1558 SSL_CTX_set_verify(
1559 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1560 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1561 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1562
1563 ScopedSSL client, server;
1564 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get())) {
1565 return false;
1566 }
1567
1568 // The peer certificate has been dropped.
1569 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1570 if (peer) {
1571 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1572 return false;
1573 }
1574
1575 SSL_SESSION *session = SSL_get_session(server.get());
1576 if (!session->peer_sha256_valid) {
1577 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1578 return false;
1579 }
1580
1581 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1582 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1583 return false;
1584 }
1585 }
1586
1587 return true;
1588}
1589
David Benjaminafc64de2016-07-19 17:12:41 +02001590static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1591 size_t expected_len) {
1592 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1593 if (!ctx) {
1594 return false;
1595 }
1596 SSL_CTX_set_max_version(ctx.get(), version);
1597 // Our default cipher list varies by CPU capabilities, so manually place the
1598 // ChaCha20 ciphers in front.
1599 if (!SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
1600 return false;
1601 }
1602 ScopedSSL ssl(SSL_new(ctx.get()));
1603 if (!ssl) {
1604 return false;
1605 }
1606 std::vector<uint8_t> client_hello;
1607 if (!GetClientHello(ssl.get(), &client_hello)) {
1608 return false;
1609 }
1610
1611 // Zero the client_random.
1612 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1613 1 + 3 + // handshake message header
1614 2; // client_version
1615 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1616 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1617 return false;
1618 }
1619 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1620
1621 if (client_hello.size() != expected_len ||
1622 memcmp(client_hello.data(), expected, expected_len) != 0) {
1623 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1624 fprintf(stderr, "Got:\n\t");
1625 for (size_t i = 0; i < client_hello.size(); i++) {
1626 fprintf(stderr, "0x%02x, ", client_hello[i]);
1627 }
1628 fprintf(stderr, "\nWanted:\n\t");
1629 for (size_t i = 0; i < expected_len; i++) {
1630 fprintf(stderr, "0x%02x, ", expected[i]);
1631 }
1632 fprintf(stderr, "\n");
1633 return false;
1634 }
1635
1636 return true;
1637}
1638
1639// Tests that our ClientHellos do not change unexpectedly.
1640static bool TestClientHello() {
1641 static const uint8_t kSSL3ClientHello[] = {
1642 0x16, 0x03, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x43, 0x03, 0x00,
1643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 0x00, 0x1c, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0,
1647 0x14, 0x00, 0x39, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35,
1648 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04, 0x00, 0xff, 0x01, 0x00,
1649 };
1650 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1651 sizeof(kSSL3ClientHello))) {
1652 return false;
1653 }
1654
1655 static const uint8_t kTLS1ClientHello[] = {
1656 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x01, 0x00,
1657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
1660 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
1661 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
1662 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1663 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1664 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1665 };
1666 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1667 sizeof(kTLS1ClientHello))) {
1668 return false;
1669 }
1670
1671 static const uint8_t kTLS11ClientHello[] = {
1672 0x16, 0x03, 0x01, 0x00, 0x66, 0x01, 0x00, 0x00, 0x62, 0x03, 0x02, 0x00,
1673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x09,
1676 0xc0, 0x13, 0x00, 0x33, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x39, 0xc0, 0x07,
1677 0xc0, 0x11, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x04,
1678 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1679 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1680 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1681 };
1682 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1683 sizeof(kTLS11ClientHello))) {
1684 return false;
1685 }
1686
1687 static const uint8_t kTLS12ClientHello[] = {
1688 0x16, 0x03, 0x01, 0x00, 0xa4, 0x01, 0x00, 0x00, 0xa0, 0x03, 0x03, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcc, 0xa9,
1692 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1693 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1694 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1695 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x9c,
1696 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a,
1697 0x00, 0x05, 0x00, 0x04, 0x01, 0x00, 0x00, 0x35, 0xff, 0x01, 0x00, 0x01,
1698 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1699 0x12, 0x00, 0x10, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04,
1700 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01,
1701 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1702 0x18,
1703 };
1704 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1705 sizeof(kTLS12ClientHello))) {
1706 return false;
1707 }
1708
1709 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1710 // implementation has settled enough that it won't change.
1711
1712 return true;
1713}
1714
David Benjamin1d128f32015-09-08 17:41:40 -04001715int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04001716 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04001717
Adam Langley10f97f32016-07-12 08:09:33 -07001718 if (!TestCipherRules() ||
1719 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
1720 !TestSSL_SESSIONEncoding(kCustomSession) ||
1721 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
1722 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
1723 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
1724 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04001725 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07001726 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
1727 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
1728 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
1729 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
1730 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
1731 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
1732 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
1733 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
1734 !TestCipherGetRFCName() ||
1735 !TestPaddingExtension() ||
1736 !TestClientCAList() ||
1737 !TestInternalSessionCache() ||
1738 !TestSequenceNumber(false /* TLS */) ||
1739 !TestSequenceNumber(true /* DTLS */) ||
1740 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04001741 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04001742 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04001743 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04001744 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02001745 !TestRetainOnlySHA256OfCerts() ||
1746 !TestClientHello()) {
Brian Smith83a82982015-04-09 16:21:10 -10001747 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04001748 return 1;
1749 }
1750
David Benjamin2e521212014-07-16 14:37:51 -04001751 printf("PASS\n");
1752 return 0;
1753}