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