blob: 8d45acea9bd92c5acaaf62fa8fd2983e4096c46a [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"
Steven Valdezcb966542016-08-17 16:56:14 -040034#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020035#include "../crypto/test/test_util.h"
36
David Benjamin721e8b72016-08-03 13:13:17 -040037#if defined(OPENSSL_WINDOWS)
38/* Windows defines struct timeval in winsock2.h. */
39OPENSSL_MSVC_PRAGMA(warning(push, 3))
40#include <winsock2.h>
41OPENSSL_MSVC_PRAGMA(warning(pop))
42#else
43#include <sys/time.h>
44#endif
45
David Benjamin1d77e562015-03-22 17:22:08 -040046
47struct ExpectedCipher {
48 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040049 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040050};
David Benjaminbb0a17c2014-09-20 15:35:39 -040051
David Benjamin1d77e562015-03-22 17:22:08 -040052struct CipherTest {
53 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050055 // The list of expected ciphers, in order.
56 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040057};
David Benjaminbb0a17c2014-09-20 15:35:39 -040058
David Benjaminfb974e62015-12-16 19:34:22 -050059static const CipherTest kCipherTests[] = {
60 // Selecting individual ciphers should work.
61 {
62 "ECDHE-ECDSA-CHACHA20-POLY1305:"
63 "ECDHE-RSA-CHACHA20-POLY1305:"
64 "ECDHE-ECDSA-AES128-GCM-SHA256:"
65 "ECDHE-RSA-AES128-GCM-SHA256",
66 {
67 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
68 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
69 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
70 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
71 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
72 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
73 },
74 },
75 // + reorders selected ciphers to the end, keeping their relative order.
76 {
77 "ECDHE-ECDSA-CHACHA20-POLY1305:"
78 "ECDHE-RSA-CHACHA20-POLY1305:"
79 "ECDHE-ECDSA-AES128-GCM-SHA256:"
80 "ECDHE-RSA-AES128-GCM-SHA256:"
81 "+aRSA",
82 {
83 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
84 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
85 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
86 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
87 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
88 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
89 },
90 },
91 // ! banishes ciphers from future selections.
92 {
93 "!aRSA:"
94 "ECDHE-ECDSA-CHACHA20-POLY1305:"
95 "ECDHE-RSA-CHACHA20-POLY1305:"
96 "ECDHE-ECDSA-AES128-GCM-SHA256:"
97 "ECDHE-RSA-AES128-GCM-SHA256",
98 {
99 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
100 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
101 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
102 },
103 },
104 // Multiple masks can be ANDed in a single rule.
105 {
106 "kRSA+AESGCM+AES128",
107 {
108 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // - removes selected ciphers, but preserves their order for future
112 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
113 // ECDHE_RSA.
114 {
115 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
116 "AESGCM+AES128+aRSA",
117 {
118 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
119 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
120 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
121 },
122 },
123 // Unknown selectors are no-ops.
124 {
125 "ECDHE-ECDSA-CHACHA20-POLY1305:"
126 "ECDHE-RSA-CHACHA20-POLY1305:"
127 "ECDHE-ECDSA-AES128-GCM-SHA256:"
128 "ECDHE-RSA-AES128-GCM-SHA256:"
129 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
130 {
131 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
132 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
133 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
134 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
135 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
136 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
137 },
138 },
139 // Square brackets specify equi-preference groups.
140 {
141 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
142 "[ECDHE-RSA-CHACHA20-POLY1305]:"
143 "ECDHE-RSA-AES128-GCM-SHA256",
144 {
145 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
146 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
147 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
148 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
149 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
150 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
151 },
152 },
153 // @STRENGTH performs a stable strength-sort of the selected ciphers and
154 // only the selected ciphers.
155 {
156 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700157 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500158 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
159 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700160 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500161 // Select ECDHE ones and sort them by strength. Ties should resolve
162 // based on the order above.
163 "kECDHE:@STRENGTH:-ALL:"
164 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
165 // by strength. Then RSA, backwards by strength.
166 "aRSA",
167 {
168 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
169 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
170 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500171 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500172 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
173 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
174 },
175 },
176 // Exact ciphers may not be used in multi-part rules; they are treated
177 // as unknown aliases.
178 {
179 "ECDHE-ECDSA-AES128-GCM-SHA256:"
180 "ECDHE-RSA-AES128-GCM-SHA256:"
181 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
182 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
183 {
184 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
185 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
186 },
187 },
188 // SSLv3 matches everything that existed before TLS 1.2.
189 {
190 "AES128-SHA:AES128-SHA256:!SSLv3",
191 {
192 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
193 },
194 },
195 // TLSv1.2 matches everything added in TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!TLSv1.2",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
200 },
201 },
202 // The two directives have no intersection.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
208 },
209 },
210 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
211 // name and not an alias. It may not be used in a multipart rule. (That the
212 // shared name works is covered by the standard tests.)
213 {
214 "ECDHE-ECDSA-CHACHA20-POLY1305:"
215 "ECDHE-RSA-CHACHA20-POLY1305:"
216 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
217 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
218 {
219 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
220 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
222 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
223 },
224 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400225};
226
227static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400228 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400229 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
230 "RSA]",
231 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400232 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400233 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400234 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400236 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400237 "",
238 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400239 // COMPLEMENTOFDEFAULT is empty.
240 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400244 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
245 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
246 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
247 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400248};
249
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700250static const char *kMustNotIncludeNull[] = {
251 "ALL",
252 "DEFAULT",
253 "ALL:!eNULL",
254 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500255 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700256 "FIPS",
257 "SHA",
258 "SHA1",
259 "RSA",
260 "SSLv3",
261 "TLSv1",
262 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700263};
264
Matt Braithwaite053931e2016-05-25 12:06:05 -0700265static const char *kMustNotIncludeCECPQ1[] = {
266 "ALL",
267 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700268 "HIGH",
269 "FIPS",
270 "SHA",
271 "SHA1",
272 "SHA256",
273 "SHA384",
274 "RSA",
275 "SSLv3",
276 "TLSv1",
277 "TLSv1.2",
278 "aRSA",
279 "RSA",
280 "aECDSA",
281 "ECDSA",
282 "AES",
283 "AES128",
284 "AES256",
285 "AESGCM",
286 "CHACHA20",
287};
288
David Benjamin1d77e562015-03-22 17:22:08 -0400289static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
290 bool in_group = false;
291 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400292 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
293 if (!in_group && list->in_group_flags[i]) {
294 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400295 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400296 }
297 fprintf(stderr, "\t");
298 if (in_group) {
299 fprintf(stderr, " ");
300 }
301 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
302 if (in_group && !list->in_group_flags[i]) {
303 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400304 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400305 }
306 }
307}
308
David Benjaminfb974e62015-12-16 19:34:22 -0500309static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700310 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400311 if (!ctx) {
312 return false;
David Benjamin65226252015-02-05 16:49:47 -0500313 }
314
David Benjaminfb974e62015-12-16 19:34:22 -0500315 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
316 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400317 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400318 }
319
David Benjamin1d77e562015-03-22 17:22:08 -0400320 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500321 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
322 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
323 PrintCipherPreferenceList(ctx->cipher_list);
324 return false;
325 }
326
327 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400328 const SSL_CIPHER *cipher =
329 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500330 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
331 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
332 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400333 PrintCipherPreferenceList(ctx->cipher_list);
334 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400335 }
336 }
337
David Benjamin1d77e562015-03-22 17:22:08 -0400338 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400339}
340
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700341static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700342 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700343 if (!ctx) {
344 return false;
345 }
346 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
347 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
348 return false;
349 }
350 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
351 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
352 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
353 return false;
354 }
355 }
356 return true;
357}
358
Matt Braithwaite053931e2016-05-25 12:06:05 -0700359static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700360 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700361 if (!ctx) {
362 return false;
363 }
364 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
365 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
366 return false;
367 }
368 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
369 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
370 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
371 return false;
372 }
373 }
374 return true;
375}
376
David Benjamin1d77e562015-03-22 17:22:08 -0400377static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500378 for (const CipherTest &test : kCipherTests) {
379 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400380 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400381 }
382 }
383
David Benjaminfb974e62015-12-16 19:34:22 -0500384 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700385 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400386 if (!ctx) {
387 return false;
David Benjamin65226252015-02-05 16:49:47 -0500388 }
David Benjaminfb974e62015-12-16 19:34:22 -0500389 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
390 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400391 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400392 }
393 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400394 }
395
David Benjaminfb974e62015-12-16 19:34:22 -0500396 for (const char *rule : kMustNotIncludeNull) {
397 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700398 return false;
399 }
400 }
401
Matt Braithwaite053931e2016-05-25 12:06:05 -0700402 for (const char *rule : kMustNotIncludeCECPQ1) {
403 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
404 return false;
405 }
406 }
407
David Benjamin1d77e562015-03-22 17:22:08 -0400408 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400409}
David Benjamin2e521212014-07-16 14:37:51 -0400410
Adam Langley10f97f32016-07-12 08:09:33 -0700411// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
412// s_client -sess_out.
413static const char kOpenSSLSession[] =
414 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
415 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
416 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
417 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
418 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
419 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
420 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
421 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
422 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
423 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
424 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
425 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
426 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
427 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
428 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
429 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
430 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
431 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
432 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
433 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
434 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
435 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
436 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
437 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
438 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
439 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
440 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
441 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
442 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
443 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
444 "i4gv7Y5oliyn";
445
446// kCustomSession is a custom serialized SSL_SESSION generated by
447// filling in missing fields from |kOpenSSLSession|. This includes
448// providing |peer_sha256|, so |peer| is not serialized.
449static const char kCustomSession[] =
450 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
451 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
452 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
453 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
454 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
455 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
456 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
457 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
458
459// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
460static const char kBoringSSLSession[] =
461 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
462 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
463 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
464 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
465 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
466 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
467 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
468 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
469 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
470 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
471 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
472 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
473 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
474 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
475 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
476 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
477 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
478 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
479 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
480 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
481 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
482 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
483 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
484 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
485 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
486 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
487 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
488 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
489 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
490 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
491 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
492 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
493 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
494 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
495 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
496 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
497 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
498 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
499 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
500 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
501 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
502 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
503 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
504 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
505 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
506 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
507 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
508 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
509 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
510 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
511 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
512 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
513 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
514 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
515 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
516 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
517 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
518 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
519 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
520 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
521 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
522 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
523 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
524 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
525 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
526 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
527 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
528 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
529 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
530 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
531 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
532 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
533 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
534 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
535 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
536 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
537 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
538 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
539 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
540 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
541 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
542 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
543 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
544 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
545 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
546 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
547 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
548 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
549 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
550 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
551 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
552 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
553 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
554 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
555 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
556
557// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
558// the final (optional) element of |kCustomSession| with tag number 30.
559static const char kBadSessionExtraField[] =
560 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
561 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
562 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
563 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
564 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
565 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
566 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
567 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
568
569// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
570// the version of |kCustomSession| with 2.
571static const char kBadSessionVersion[] =
572 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
573 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
574 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
575 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
576 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
577 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
578 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
579 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
580
581// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
582// appended.
583static const char kBadSessionTrailingData[] =
584 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
585 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
586 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
587 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
588 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
589 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
590 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
591 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
592
David Benjamin1d77e562015-03-22 17:22:08 -0400593static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400594 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400595 if (!EVP_DecodedLength(&len, strlen(in))) {
596 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400597 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400598 }
599
David Benjamin1d77e562015-03-22 17:22:08 -0400600 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800601 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400602 strlen(in))) {
603 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400604 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400605 }
David Benjamin1d77e562015-03-22 17:22:08 -0400606 out->resize(len);
607 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400608}
609
David Benjamin1d77e562015-03-22 17:22:08 -0400610static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400611 const uint8_t *cptr;
612 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400613
David Benjamin1d77e562015-03-22 17:22:08 -0400614 // Decode the input.
615 std::vector<uint8_t> input;
616 if (!DecodeBase64(&input, input_b64)) {
617 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400618 }
619
David Benjamin1d77e562015-03-22 17:22:08 -0400620 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700621 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400622 if (!session) {
623 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400624 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400625 }
626
David Benjamin1d77e562015-03-22 17:22:08 -0400627 // Verify the SSL_SESSION encoding round-trips.
628 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700629 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400630 uint8_t *encoded_raw;
631 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400632 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400633 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400634 }
David Benjamin1d77e562015-03-22 17:22:08 -0400635 encoded.reset(encoded_raw);
636 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800637 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400638 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200639 hexdump(stderr, "Before: ", input.data(), input.size());
640 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400641 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400642 }
David Benjamin3cac4502014-10-21 01:46:30 -0400643
David Benjaminfd67aa82015-06-15 19:41:48 -0400644 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800645 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400646 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800647 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400648 fprintf(stderr, "d2i_SSL_SESSION failed\n");
649 return false;
650 }
651
David Benjamin1d77e562015-03-22 17:22:08 -0400652 // Verify the SSL_SESSION encoding round-trips via the legacy API.
653 int len = i2d_SSL_SESSION(session.get(), NULL);
654 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400655 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400656 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400657 }
658
David Benjamin1d77e562015-03-22 17:22:08 -0400659 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
660 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400661 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400662 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400663 }
David Benjamin1d77e562015-03-22 17:22:08 -0400664
665 ptr = encoded.get();
666 len = i2d_SSL_SESSION(session.get(), &ptr);
667 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400668 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400669 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400670 }
David Benjamin1d77e562015-03-22 17:22:08 -0400671 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400672 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400673 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400674 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800675 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400676 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400677 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400678 }
679
David Benjamin1d77e562015-03-22 17:22:08 -0400680 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400681}
682
David Benjaminf297e022015-05-28 19:55:29 -0400683static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
684 std::vector<uint8_t> input;
685 if (!DecodeBase64(&input, input_b64)) {
686 return false;
687 }
688
689 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700690 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400691 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400692 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400693 return false;
694 }
695 ERR_clear_error();
696 return true;
697}
698
David Benjamin10e664b2016-06-20 22:20:47 -0400699static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400700 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700701 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400702 if (!ctx) {
703 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500704 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400705 if (ctx->min_version != min_version || ctx->max_version != max_version) {
706 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
707 ctx->min_version, ctx->max_version, min_version, max_version);
708 return false;
709 }
710 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500711}
712
David Benjamin1d77e562015-03-22 17:22:08 -0400713static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500714 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
715 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400716 return false;
David Benjamin65226252015-02-05 16:49:47 -0500717 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700718 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400719 if (!rfc_name) {
720 return false;
721 }
David Benjamin67be0482015-04-20 16:19:00 -0400722 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400723 return true;
David Benjamin65226252015-02-05 16:49:47 -0500724}
725
726typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500727 int id;
David Benjamin65226252015-02-05 16:49:47 -0500728 const char *rfc_name;
729} CIPHER_RFC_NAME_TEST;
730
731static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500732 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500733 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500734 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
735 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
736 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500737 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
738 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
739 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
740 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
741 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
742 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
743 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
744 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
745 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
746 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
Adam Langley85bc5602015-06-09 09:54:04 -0700747 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
748 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500749 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
750 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400751 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000752 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500753 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000754 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500755 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500756};
757
David Benjamin1d77e562015-03-22 17:22:08 -0400758static bool TestCipherGetRFCName(void) {
759 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400760 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500761 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400762 std::string rfc_name;
763 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
764 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
765 return false;
David Benjamin65226252015-02-05 16:49:47 -0500766 }
David Benjamin1d77e562015-03-22 17:22:08 -0400767 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500768 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400769 rfc_name.c_str(), test->rfc_name);
770 return false;
David Benjamin65226252015-02-05 16:49:47 -0500771 }
David Benjamin65226252015-02-05 16:49:47 -0500772 }
David Benjamin1d77e562015-03-22 17:22:08 -0400773 return true;
David Benjamin65226252015-02-05 16:49:47 -0500774}
775
David Benjamin422fe082015-07-21 22:03:43 -0400776// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
777// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700778static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400779 std::vector<uint8_t> der;
780 if (!DecodeBase64(&der, kOpenSSLSession)) {
781 return nullptr;
782 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700783 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400784 if (!session) {
785 return nullptr;
786 }
787
788 // Swap out the ticket for a garbage one.
789 OPENSSL_free(session->tlsext_tick);
790 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
791 if (session->tlsext_tick == nullptr) {
792 return nullptr;
793 }
794 memset(session->tlsext_tick, 'a', ticket_len);
795 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400796
797 // Fix up the timeout.
798 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400799 return session;
800}
801
David Benjaminafc64de2016-07-19 17:12:41 +0200802static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700803 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200804 if (!bio) {
805 return false;
806 }
807 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400808 BIO_up_ref(bio.get());
809 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200810 int ret = SSL_connect(ssl);
811 if (ret > 0) {
812 // SSL_connect should fail without a BIO to write to.
813 return false;
814 }
815 ERR_clear_error();
816
817 const uint8_t *client_hello;
818 size_t client_hello_len;
819 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
820 return false;
821 }
822 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
823 return true;
824}
825
David Benjamin422fe082015-07-21 22:03:43 -0400826// GetClientHelloLen creates a client SSL connection with a ticket of length
827// |ticket_len| and records the ClientHello. It returns the length of the
828// ClientHello, not including the record header, on success and zero on error.
829static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700830 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
831 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400832 if (!ctx || !session) {
833 return 0;
834 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700835 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200836 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400837 return 0;
838 }
David Benjaminafc64de2016-07-19 17:12:41 +0200839 std::vector<uint8_t> client_hello;
840 if (!GetClientHello(ssl.get(), &client_hello) ||
841 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400842 return 0;
843 }
David Benjaminafc64de2016-07-19 17:12:41 +0200844 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400845}
846
847struct PaddingTest {
848 size_t input_len, padded_len;
849};
850
851static const PaddingTest kPaddingTests[] = {
852 // ClientHellos of length below 0x100 do not require padding.
853 {0xfe, 0xfe},
854 {0xff, 0xff},
855 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
856 {0x100, 0x200},
857 {0x123, 0x200},
858 {0x1fb, 0x200},
859 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
860 // padding extension takes a minimum of four bytes plus one required content
861 // byte. (To work around yet more server bugs, we avoid empty final
862 // extensions.)
863 {0x1fc, 0x201},
864 {0x1fd, 0x202},
865 {0x1fe, 0x203},
866 {0x1ff, 0x204},
867 // Finally, larger ClientHellos need no padding.
868 {0x200, 0x200},
869 {0x201, 0x201},
870};
871
872static bool TestPaddingExtension() {
873 // Sample a baseline length.
874 size_t base_len = GetClientHelloLen(1);
875 if (base_len == 0) {
876 return false;
877 }
878
879 for (const PaddingTest &test : kPaddingTests) {
880 if (base_len > test.input_len) {
881 fprintf(stderr, "Baseline ClientHello too long.\n");
882 return false;
883 }
884
885 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
886 if (padded_len != test.padded_len) {
887 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
888 static_cast<unsigned>(test.input_len),
889 static_cast<unsigned>(padded_len),
890 static_cast<unsigned>(test.padded_len));
891 return false;
892 }
893 }
894 return true;
895}
896
David Benjamin1d128f32015-09-08 17:41:40 -0400897// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
898// before configuring as a server.
899static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700900 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400901 if (!ctx) {
902 return false;
903 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700904 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400905 if (!ssl) {
906 return false;
907 }
908
909 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
910 if (stack == nullptr) {
911 return false;
912 }
913 // |SSL_set_client_CA_list| takes ownership.
914 SSL_set_client_CA_list(ssl.get(), stack);
915
916 return SSL_get_client_CA_list(ssl.get()) == stack;
917}
918
David Benjamin0f653952015-10-18 14:28:01 -0400919static void AppendSession(SSL_SESSION *session, void *arg) {
920 std::vector<SSL_SESSION*> *out =
921 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
922 out->push_back(session);
923}
924
925// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
926// order.
927static bool ExpectCache(SSL_CTX *ctx,
928 const std::vector<SSL_SESSION*> &expected) {
929 // Check the linked list.
930 SSL_SESSION *ptr = ctx->session_cache_head;
931 for (SSL_SESSION *session : expected) {
932 if (ptr != session) {
933 return false;
934 }
935 // TODO(davidben): This is an absurd way to denote the end of the list.
936 if (ptr->next ==
937 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
938 ptr = nullptr;
939 } else {
940 ptr = ptr->next;
941 }
942 }
943 if (ptr != nullptr) {
944 return false;
945 }
946
947 // Check the hash table.
948 std::vector<SSL_SESSION*> actual, expected_copy;
949 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
950 expected_copy = expected;
951
952 std::sort(actual.begin(), actual.end());
953 std::sort(expected_copy.begin(), expected_copy.end());
954
955 return actual == expected_copy;
956}
957
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700958static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
959 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -0400960 if (!ret) {
961 return nullptr;
962 }
963
964 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
965 memset(ret->session_id, 0, ret->session_id_length);
966 memcpy(ret->session_id, &number, sizeof(number));
967 return ret;
968}
969
David Benjamin0f653952015-10-18 14:28:01 -0400970// Test that the internal session cache behaves as expected.
971static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700972 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -0400973 if (!ctx) {
974 return false;
975 }
976
977 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700978 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400979 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700980 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -0400981 if (!session) {
982 return false;
983 }
David Benjamin4f6acaf2015-11-21 03:00:50 -0500984 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -0400985 }
986
987 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
988
989 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500990 for (const auto &session : sessions) {
991 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -0400992 return false;
993 }
994 }
995
996 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500997 std::vector<SSL_SESSION*> expected = {
998 sessions[9].get(),
999 sessions[8].get(),
1000 sessions[7].get(),
1001 sessions[6].get(),
1002 sessions[5].get(),
1003 };
David Benjamin0f653952015-10-18 14:28:01 -04001004 if (!ExpectCache(ctx.get(), expected)) {
1005 return false;
1006 }
1007
1008 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001009 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001010 !ExpectCache(ctx.get(), expected)) {
1011 return false;
1012 }
1013
1014 // Although collisions should be impossible (256-bit session IDs), the cache
1015 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001016 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001017 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1018 return false;
1019 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001020 expected = {
1021 collision.get(),
1022 sessions[9].get(),
1023 sessions[8].get(),
1024 sessions[6].get(),
1025 sessions[5].get(),
1026 };
David Benjamin0f653952015-10-18 14:28:01 -04001027 if (!ExpectCache(ctx.get(), expected)) {
1028 return false;
1029 }
1030
1031 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001032 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001033 return false;
1034 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001035 expected = {
1036 collision.get(),
1037 sessions[9].get(),
1038 sessions[8].get(),
1039 sessions[5].get(),
1040 };
David Benjamin0f653952015-10-18 14:28:01 -04001041 if (!ExpectCache(ctx.get(), expected)) {
1042 return false;
1043 }
1044
1045 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001046 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1047 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001048 !ExpectCache(ctx.get(), expected)) {
1049 return false;
1050 }
1051
1052 return true;
1053}
1054
David Benjaminde942382016-02-11 12:02:01 -05001055static uint16_t EpochFromSequence(uint64_t seq) {
1056 return static_cast<uint16_t>(seq >> 48);
1057}
1058
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001059static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001060 static const char kCertPEM[] =
1061 "-----BEGIN CERTIFICATE-----\n"
1062 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1063 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1064 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1065 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1066 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1067 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1068 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1069 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1070 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1071 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1072 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1073 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1074 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1075 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001076 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1077 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001078}
1079
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001080static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001081 static const char kKeyPEM[] =
1082 "-----BEGIN RSA PRIVATE KEY-----\n"
1083 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1084 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1085 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1086 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1087 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1088 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1089 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1090 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1091 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1092 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1093 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1094 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1095 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1096 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001097 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1098 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001099 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1100}
1101
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001102static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001103 static const char kCertPEM[] =
1104 "-----BEGIN CERTIFICATE-----\n"
1105 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1106 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1107 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1108 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1109 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1110 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1111 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1112 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1113 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1114 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1115 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001116 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1117 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001118}
1119
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001120static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001121 static const char kKeyPEM[] =
1122 "-----BEGIN PRIVATE KEY-----\n"
1123 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1124 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1125 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1126 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001127 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1128 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001129 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1130}
1131
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001132static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001133 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1134 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001135 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001136 if (!client || !server) {
1137 return false;
1138 }
1139 SSL_set_connect_state(client.get());
1140 SSL_set_accept_state(server.get());
1141
David Benjamina20e5352016-08-02 19:09:41 -04001142 SSL_set_session(client.get(), session);
1143
David Benjaminde942382016-02-11 12:02:01 -05001144 BIO *bio1, *bio2;
1145 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1146 return false;
1147 }
1148 // SSL_set_bio takes ownership.
1149 SSL_set_bio(client.get(), bio1, bio1);
1150 SSL_set_bio(server.get(), bio2, bio2);
1151
1152 // Drive both their handshakes to completion.
1153 for (;;) {
1154 int client_ret = SSL_do_handshake(client.get());
1155 int client_err = SSL_get_error(client.get(), client_ret);
1156 if (client_err != SSL_ERROR_NONE &&
1157 client_err != SSL_ERROR_WANT_READ &&
1158 client_err != SSL_ERROR_WANT_WRITE) {
1159 fprintf(stderr, "Client error: %d\n", client_err);
1160 return false;
1161 }
1162
1163 int server_ret = SSL_do_handshake(server.get());
1164 int server_err = SSL_get_error(server.get(), server_ret);
1165 if (server_err != SSL_ERROR_NONE &&
1166 server_err != SSL_ERROR_WANT_READ &&
1167 server_err != SSL_ERROR_WANT_WRITE) {
1168 fprintf(stderr, "Server error: %d\n", server_err);
1169 return false;
1170 }
1171
1172 if (client_ret == 1 && server_ret == 1) {
1173 break;
1174 }
1175 }
1176
David Benjamin686bb192016-05-10 15:15:41 -04001177 *out_client = std::move(client);
1178 *out_server = std::move(server);
1179 return true;
1180}
1181
1182static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001183 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1184 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001185 if (!client_ctx || !server_ctx) {
1186 return false;
1187 }
1188
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001189 bssl::UniquePtr<X509> cert = GetTestCertificate();
1190 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001191 if (!cert || !key ||
1192 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1193 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1194 return false;
1195 }
1196
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001197 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001198 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001199 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001200 return false;
1201 }
1202
David Benjaminde942382016-02-11 12:02:01 -05001203 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1204 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1205 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1206 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1207
1208 if (dtls) {
1209 // Both client and server must be at epoch 1.
1210 if (EpochFromSequence(client_read_seq) != 1 ||
1211 EpochFromSequence(client_write_seq) != 1 ||
1212 EpochFromSequence(server_read_seq) != 1 ||
1213 EpochFromSequence(server_write_seq) != 1) {
1214 fprintf(stderr, "Bad epochs.\n");
1215 return false;
1216 }
1217
1218 // The next record to be written should exceed the largest received.
1219 if (client_write_seq <= server_read_seq ||
1220 server_write_seq <= client_read_seq) {
1221 fprintf(stderr, "Inconsistent sequence numbers.\n");
1222 return false;
1223 }
1224 } else {
1225 // The next record to be written should equal the next to be received.
1226 if (client_write_seq != server_read_seq ||
1227 server_write_seq != client_write_seq) {
1228 fprintf(stderr, "Inconsistent sequence numbers.\n");
1229 return false;
1230 }
1231 }
1232
1233 // Send a record from client to server.
1234 uint8_t byte = 0;
1235 if (SSL_write(client.get(), &byte, 1) != 1 ||
1236 SSL_read(server.get(), &byte, 1) != 1) {
1237 fprintf(stderr, "Could not send byte.\n");
1238 return false;
1239 }
1240
1241 // The client write and server read sequence numbers should have incremented.
1242 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1243 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1244 fprintf(stderr, "Sequence numbers did not increment.\n");\
1245 return false;
1246 }
1247
1248 return true;
1249}
1250
David Benjamin686bb192016-05-10 15:15:41 -04001251static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001252 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1253 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001254 if (!client_ctx || !server_ctx) {
1255 return false;
1256 }
1257
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001258 bssl::UniquePtr<X509> cert = GetTestCertificate();
1259 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001260 if (!cert || !key ||
1261 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1262 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1263 return false;
1264 }
1265
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001266 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001267 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001268 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001269 return false;
1270 }
1271
1272 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1273 // one side has shut down.
1274 if (SSL_shutdown(client.get()) != 0) {
1275 fprintf(stderr, "Could not shutdown.\n");
1276 return false;
1277 }
1278
1279 // Reading from the server should consume the EOF.
1280 uint8_t byte;
1281 if (SSL_read(server.get(), &byte, 1) != 0 ||
1282 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1283 fprintf(stderr, "Connection was not shut down cleanly.\n");
1284 return false;
1285 }
1286
1287 // However, the server may continue to write data and then shut down the
1288 // connection.
1289 byte = 42;
1290 if (SSL_write(server.get(), &byte, 1) != 1 ||
1291 SSL_read(client.get(), &byte, 1) != 1 ||
1292 byte != 42) {
1293 fprintf(stderr, "Could not send byte.\n");
1294 return false;
1295 }
1296
1297 // The server may then shutdown the connection.
1298 if (SSL_shutdown(server.get()) != 1 ||
1299 SSL_shutdown(client.get()) != 1) {
1300 fprintf(stderr, "Could not complete shutdown.\n");
1301 return false;
1302 }
1303
1304 return true;
1305}
Steven Valdez87eab492016-06-27 16:34:59 -04001306static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001307 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1308 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001309 if (!client_ctx || !server_ctx) {
1310 return false;
1311 }
1312
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001313 bssl::UniquePtr<X509> cert = GetTestCertificate();
1314 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001315 if (!cert || !key ||
1316 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1317 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1318 return false;
1319 }
1320
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001321 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001322 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001323 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001324 return false;
1325 }
1326
1327 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001328 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001329 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001330 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001331 }
David Benjamin4501bd52016-08-01 13:39:41 -04001332
Steven Valdez84b5c002016-08-25 16:30:58 -04001333 session1->not_resumable = 0;
1334
Steven Valdez87eab492016-06-27 16:34:59 -04001335 uint8_t *s0_bytes, *s1_bytes;
1336 size_t s0_len, s1_len;
1337
1338 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1339 return false;
1340 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001341 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001342
1343 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1344 return false;
1345 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001346 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001347
1348 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1349}
David Benjamin686bb192016-05-10 15:15:41 -04001350
David Benjamin5c0fb882016-06-14 14:03:51 -04001351static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1352 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1353 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1354 SSL_get_wfd(ssl), rfd, wfd);
1355 return false;
1356 }
1357
1358 // The wrapper BIOs are always equal when fds are equal, even if set
1359 // individually.
1360 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1361 fprintf(stderr, "rbio and wbio did not match.\n");
1362 return false;
1363 }
1364
1365 return true;
1366}
1367
1368static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001369 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001370 if (!ctx) {
1371 return false;
1372 }
1373
1374 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001375 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001376 if (!ssl ||
1377 !SSL_set_rfd(ssl.get(), 1) ||
1378 !SSL_set_wfd(ssl.get(), 2) ||
1379 !ExpectFDs(ssl.get(), 1, 2)) {
1380 return false;
1381 }
1382
1383 // Test setting the same FD.
1384 ssl.reset(SSL_new(ctx.get()));
1385 if (!ssl ||
1386 !SSL_set_fd(ssl.get(), 1) ||
1387 !ExpectFDs(ssl.get(), 1, 1)) {
1388 return false;
1389 }
1390
1391 // Test setting the same FD one side at a time.
1392 ssl.reset(SSL_new(ctx.get()));
1393 if (!ssl ||
1394 !SSL_set_rfd(ssl.get(), 1) ||
1395 !SSL_set_wfd(ssl.get(), 1) ||
1396 !ExpectFDs(ssl.get(), 1, 1)) {
1397 return false;
1398 }
1399
1400 // Test setting the same FD in the other order.
1401 ssl.reset(SSL_new(ctx.get()));
1402 if (!ssl ||
1403 !SSL_set_wfd(ssl.get(), 1) ||
1404 !SSL_set_rfd(ssl.get(), 1) ||
1405 !ExpectFDs(ssl.get(), 1, 1)) {
1406 return false;
1407 }
1408
David Benjamin5c0fb882016-06-14 14:03:51 -04001409 // Test changing the read FD partway through.
1410 ssl.reset(SSL_new(ctx.get()));
1411 if (!ssl ||
1412 !SSL_set_fd(ssl.get(), 1) ||
1413 !SSL_set_rfd(ssl.get(), 2) ||
1414 !ExpectFDs(ssl.get(), 2, 1)) {
1415 return false;
1416 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001417
1418 // Test changing the write FD partway through.
1419 ssl.reset(SSL_new(ctx.get()));
1420 if (!ssl ||
1421 !SSL_set_fd(ssl.get(), 1) ||
1422 !SSL_set_wfd(ssl.get(), 2) ||
1423 !ExpectFDs(ssl.get(), 1, 2)) {
1424 return false;
1425 }
1426
1427 // Test a no-op change to the read FD partway through.
1428 ssl.reset(SSL_new(ctx.get()));
1429 if (!ssl ||
1430 !SSL_set_fd(ssl.get(), 1) ||
1431 !SSL_set_rfd(ssl.get(), 1) ||
1432 !ExpectFDs(ssl.get(), 1, 1)) {
1433 return false;
1434 }
1435
1436 // Test a no-op change to the write FD partway through.
1437 ssl.reset(SSL_new(ctx.get()));
1438 if (!ssl ||
1439 !SSL_set_fd(ssl.get(), 1) ||
1440 !SSL_set_wfd(ssl.get(), 1) ||
1441 !ExpectFDs(ssl.get(), 1, 1)) {
1442 return false;
1443 }
1444
1445 // ASan builds will implicitly test that the internal |BIO| reference-counting
1446 // is correct.
1447
1448 return true;
1449}
1450
David Benjamin4501bd52016-08-01 13:39:41 -04001451static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001452 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001453 if (!ctx) {
1454 return false;
1455 }
1456
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001457 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1458 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001459 bio3(BIO_new(BIO_s_mem()));
1460 if (!ssl || !bio1 || !bio2 || !bio3) {
1461 return false;
1462 }
1463
1464 // SSL_set_bio takes one reference when the parameters are the same.
1465 BIO_up_ref(bio1.get());
1466 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1467
1468 // Repeating the call does nothing.
1469 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1470
1471 // It takes one reference each when the parameters are different.
1472 BIO_up_ref(bio2.get());
1473 BIO_up_ref(bio3.get());
1474 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1475
1476 // Repeating the call does nothing.
1477 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1478
1479 // It takes one reference when changing only wbio.
1480 BIO_up_ref(bio1.get());
1481 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1482
1483 // It takes one reference when changing only rbio and the two are different.
1484 BIO_up_ref(bio3.get());
1485 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1486
1487 // If setting wbio to rbio, it takes no additional references.
1488 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1489
1490 // From there, wbio may be switched to something else.
1491 BIO_up_ref(bio1.get());
1492 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1493
1494 // If setting rbio to wbio, it takes no additional references.
1495 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1496
1497 // From there, rbio may be switched to something else, but, for historical
1498 // reasons, it takes a reference to both parameters.
1499 BIO_up_ref(bio1.get());
1500 BIO_up_ref(bio2.get());
1501 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1502
1503 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1504 // is correct.
1505 return true;
1506}
1507
David Benjamin25490f22016-07-14 00:22:54 -04001508static uint16_t kVersions[] = {
1509 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1510};
1511
1512static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1513
David Benjaminadd5e522016-07-14 00:33:24 -04001514static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001515 bssl::UniquePtr<X509> cert = GetTestCertificate();
1516 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001517 if (!cert || !key) {
1518 return false;
1519 }
1520
1521 for (uint16_t version : kVersions) {
1522 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001523 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001524 if (!ctx ||
1525 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1526 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1527 return false;
1528 }
1529 SSL_CTX_set_min_version(ctx.get(), version);
1530 SSL_CTX_set_max_version(ctx.get(), version);
1531 SSL_CTX_set_verify(
1532 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1533 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1534
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001535 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001536 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1537 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001538 return false;
1539 }
1540
1541 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001542 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001543 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1544 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1545 return false;
1546 }
1547
1548 peer.reset(SSL_get_peer_certificate(client.get()));
1549 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1550 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1551 return false;
1552 }
1553
1554 // However, for historical reasons, the chain includes the leaf on the
1555 // client, but does not on the server.
1556 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1557 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1558 return false;
1559 }
1560
1561 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1562 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1563 return false;
1564 }
1565 }
1566
1567 return true;
1568}
1569
David Benjamin25490f22016-07-14 00:22:54 -04001570static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001571 bssl::UniquePtr<X509> cert = GetTestCertificate();
1572 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001573 if (!cert || !key) {
1574 return false;
1575 }
1576
1577 uint8_t *cert_der = NULL;
1578 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1579 if (cert_der_len < 0) {
1580 return false;
1581 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001582 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001583
1584 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1585 SHA256(cert_der, cert_der_len, cert_sha256);
1586
1587 for (uint16_t version : kVersions) {
1588 // Configure both client and server to accept any certificate, but the
1589 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001590 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001591 if (!ctx ||
1592 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1593 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1594 return false;
1595 }
1596 SSL_CTX_set_min_version(ctx.get(), version);
1597 SSL_CTX_set_max_version(ctx.get(), version);
1598 SSL_CTX_set_verify(
1599 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1600 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1601 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1602
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001603 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001604 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1605 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001606 return false;
1607 }
1608
1609 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001610 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001611 if (peer) {
1612 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1613 return false;
1614 }
1615
1616 SSL_SESSION *session = SSL_get_session(server.get());
1617 if (!session->peer_sha256_valid) {
1618 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1619 return false;
1620 }
1621
1622 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1623 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1624 return false;
1625 }
1626 }
1627
1628 return true;
1629}
1630
David Benjaminafc64de2016-07-19 17:12:41 +02001631static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1632 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001633 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminafc64de2016-07-19 17:12:41 +02001634 if (!ctx) {
1635 return false;
1636 }
1637 SSL_CTX_set_max_version(ctx.get(), version);
1638 // Our default cipher list varies by CPU capabilities, so manually place the
1639 // ChaCha20 ciphers in front.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -07001640 if (!SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001641 return false;
1642 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001643 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001644 if (!ssl) {
1645 return false;
1646 }
1647 std::vector<uint8_t> client_hello;
1648 if (!GetClientHello(ssl.get(), &client_hello)) {
1649 return false;
1650 }
1651
1652 // Zero the client_random.
1653 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1654 1 + 3 + // handshake message header
1655 2; // client_version
1656 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1657 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1658 return false;
1659 }
1660 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1661
1662 if (client_hello.size() != expected_len ||
1663 memcmp(client_hello.data(), expected, expected_len) != 0) {
1664 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1665 fprintf(stderr, "Got:\n\t");
1666 for (size_t i = 0; i < client_hello.size(); i++) {
1667 fprintf(stderr, "0x%02x, ", client_hello[i]);
1668 }
1669 fprintf(stderr, "\nWanted:\n\t");
1670 for (size_t i = 0; i < expected_len; i++) {
1671 fprintf(stderr, "0x%02x, ", expected[i]);
1672 }
1673 fprintf(stderr, "\n");
1674 return false;
1675 }
1676
1677 return true;
1678}
1679
1680// Tests that our ClientHellos do not change unexpectedly.
1681static bool TestClientHello() {
1682 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001683 0x16,
1684 0x03, 0x00,
1685 0x00, 0x3f,
1686 0x01,
1687 0x00, 0x00, 0x3b,
1688 0x03, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1693 0x00,
1694 0x00, 0x14,
1695 0xc0, 0x09,
1696 0xc0, 0x13,
1697 0x00, 0x33,
1698 0xc0, 0x0a,
1699 0xc0, 0x14,
1700 0x00, 0x39,
1701 0x00, 0x2f,
1702 0x00, 0x35,
1703 0x00, 0x0a,
1704 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001705 };
1706 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1707 sizeof(kSSL3ClientHello))) {
1708 return false;
1709 }
1710
1711 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001712 0x16,
1713 0x03, 0x01,
1714 0x00, 0x5e,
1715 0x01,
1716 0x00, 0x00, 0x5a,
1717 0x03, 0x01,
1718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722 0x00,
1723 0x00, 0x12,
1724 0xc0, 0x09,
1725 0xc0, 0x13,
1726 0x00, 0x33,
1727 0xc0, 0x0a,
1728 0xc0, 0x14,
1729 0x00, 0x39,
1730 0x00, 0x2f,
1731 0x00, 0x35,
1732 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001733 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1734 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1735 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1736 };
1737 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1738 sizeof(kTLS1ClientHello))) {
1739 return false;
1740 }
1741
1742 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001743 0x16,
1744 0x03, 0x01,
1745 0x00, 0x5e,
1746 0x01,
1747 0x00, 0x00, 0x5a,
1748 0x03, 0x02,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1753 0x00,
1754 0x00, 0x12,
1755 0xc0, 0x09,
1756 0xc0, 0x13,
1757 0x00, 0x33,
1758 0xc0, 0x0a,
1759 0xc0, 0x14,
1760 0x00, 0x39,
1761 0x00, 0x2f,
1762 0x00, 0x35,
1763 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001764 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1765 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1766 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1767 };
1768 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1769 sizeof(kTLS11ClientHello))) {
1770 return false;
1771 }
1772
1773 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001774 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1778 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1779 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1780 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1781 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1782 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1783 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
1784 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x07, 0x02, 0x06, 0x01, 0x06,
1785 0x03, 0x07, 0x01, 0x05, 0x01, 0x05, 0x03, 0x07, 0x00, 0x04, 0x01, 0x04,
1786 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1787 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001788 };
1789 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1790 sizeof(kTLS12ClientHello))) {
1791 return false;
1792 }
1793
1794 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1795 // implementation has settled enough that it won't change.
1796
1797 return true;
1798}
1799
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001800static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001801
1802static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1803 // Save the most recent session.
1804 g_last_session.reset(session);
1805 return 1;
1806}
1807
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001808static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001809 SSL_CTX *server_ctx) {
1810 g_last_session = nullptr;
1811 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1812
1813 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001814 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001815 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1816 nullptr /* no session */)) {
1817 fprintf(stderr, "Failed to connect client and server.\n");
1818 return nullptr;
1819 }
1820
1821 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1822 SSL_read(client.get(), nullptr, 0);
1823
1824 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1825
1826 if (!g_last_session) {
1827 fprintf(stderr, "Client did not receive a session.\n");
1828 return nullptr;
1829 }
1830 return std::move(g_last_session);
1831}
1832
1833static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1834 SSL_SESSION *session,
1835 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001836 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001837 if (!ConnectClientAndServer(&client, &server, client_ctx,
1838 server_ctx, session)) {
1839 fprintf(stderr, "Failed to connect client and server.\n");
1840 return false;
1841 }
1842
1843 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1844 fprintf(stderr, "Client and server were inconsistent.\n");
1845 return false;
1846 }
1847
1848 bool was_reused = !!SSL_session_reused(client.get());
1849 if (was_reused != reused) {
1850 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1851 was_reused ? "" : " not");
1852 return false;
1853 }
1854
1855 return true;
1856}
1857
1858static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001859 bssl::UniquePtr<X509> cert = GetTestCertificate();
1860 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001861 if (!cert || !key) {
1862 return false;
1863 }
1864
1865 static const uint8_t kContext1[] = {1};
1866 static const uint8_t kContext2[] = {2};
1867
1868 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001869 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1870 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001871 if (!server_ctx || !client_ctx ||
1872 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1873 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1874 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
1875 sizeof(kContext1))) {
1876 return false;
1877 }
1878
1879 SSL_CTX_set_min_version(client_ctx.get(), version);
1880 SSL_CTX_set_max_version(client_ctx.get(), version);
1881 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1882
1883 SSL_CTX_set_min_version(server_ctx.get(), version);
1884 SSL_CTX_set_max_version(server_ctx.get(), version);
1885 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1886
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001887 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001888 CreateClientSession(client_ctx.get(), server_ctx.get());
1889 if (!session) {
1890 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1891 return false;
1892 }
1893
1894 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1895 true /* expect session reused */)) {
1896 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1897 return false;
1898 }
1899
1900 // Change the session ID context.
1901 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1902 sizeof(kContext2))) {
1903 return false;
1904 }
1905
1906 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1907 false /* expect session not reused */)) {
1908 fprintf(stderr,
1909 "Error connection with different context (version = %04x).\n",
1910 version);
1911 return false;
1912 }
1913 }
1914
1915 return true;
1916}
1917
David Benjamin721e8b72016-08-03 13:13:17 -04001918static timeval g_current_time;
1919
1920static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1921 *out_clock = g_current_time;
1922}
1923
1924static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001925 bssl::UniquePtr<X509> cert = GetTestCertificate();
1926 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04001927 if (!cert || !key) {
1928 return false;
1929 }
1930
1931 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001932 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1933 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04001934 if (!server_ctx || !client_ctx ||
1935 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1936 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1937 return false;
1938 }
1939
1940 SSL_CTX_set_min_version(client_ctx.get(), version);
1941 SSL_CTX_set_max_version(client_ctx.get(), version);
1942 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1943
1944 SSL_CTX_set_min_version(server_ctx.get(), version);
1945 SSL_CTX_set_max_version(server_ctx.get(), version);
1946 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1947 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1948
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001949 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04001950 CreateClientSession(client_ctx.get(), server_ctx.get());
1951 if (!session) {
1952 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1953 return false;
1954 }
1955
1956 // Advance the clock just behind the timeout.
1957 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
1958
1959 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1960 true /* expect session reused */)) {
1961 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1962 return false;
1963 }
1964
1965 // Advance the clock one more second.
1966 g_current_time.tv_sec++;
1967
1968 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1969 false /* expect session not reused */)) {
1970 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1971 return false;
1972 }
1973 }
1974
1975 return true;
1976}
1977
David Benjamin0fc37ef2016-08-17 15:29:46 -04001978static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
1979 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
1980 SSL_set_SSL_CTX(ssl, ctx);
1981 return SSL_TLSEXT_ERR_OK;
1982}
1983
1984static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001985 bssl::UniquePtr<X509> cert = GetTestCertificate();
1986 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1987 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
1988 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04001989 if (!cert || !key || !cert2 || !key2) {
1990 return false;
1991 }
1992
1993 // At each version, test that switching the |SSL_CTX| at the SNI callback
1994 // behaves correctly.
1995 for (uint16_t version : kVersions) {
1996 if (version == SSL3_VERSION) {
1997 continue;
1998 }
1999
2000 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2001
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002002 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2003 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2004 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002005 if (!server_ctx || !server_ctx2 || !client_ctx ||
2006 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2007 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2008 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2009 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2010 // Historically signing preferences would be lost in some cases with the
2011 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2012 // this doesn't happen when |version| is TLS 1.2, configure the private
2013 // key to only sign SHA-256.
2014 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2015 &kECDSAWithSHA256, 1)) {
2016 return false;
2017 }
2018
2019 SSL_CTX_set_min_version(client_ctx.get(), version);
2020 SSL_CTX_set_max_version(client_ctx.get(), version);
2021 SSL_CTX_set_min_version(server_ctx.get(), version);
2022 SSL_CTX_set_max_version(server_ctx.get(), version);
2023 SSL_CTX_set_min_version(server_ctx2.get(), version);
2024 SSL_CTX_set_max_version(server_ctx2.get(), version);
2025
2026 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2027 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2028
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002029 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002030 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2031 server_ctx.get(), nullptr)) {
2032 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2033 return false;
2034 }
2035
2036 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002037 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002038 if (!peer ||
2039 X509_cmp(peer.get(), cert2.get()) != 0) {
2040 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2041 version);
2042 return false;
2043 }
2044 }
2045
2046 return true;
2047}
2048
David Benjamin99620572016-08-30 00:35:36 -04002049static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
2050 SSL_set_max_version(ctx->ssl, TLS1_2_VERSION);
2051 return 1;
2052}
2053
2054// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2055// maximum version.
2056static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002057 bssl::UniquePtr<X509> cert = GetTestCertificate();
2058 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2059 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2060 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002061 if (!cert || !key || !server_ctx || !client_ctx ||
2062 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2063 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
2064 return false;
2065 }
2066
2067 SSL_CTX_set_max_version(client_ctx.get(), TLS1_3_VERSION);
2068 SSL_CTX_set_max_version(server_ctx.get(), TLS1_3_VERSION);
2069
2070 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2071
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002072 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002073 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2074 server_ctx.get(), nullptr)) {
2075 return false;
2076 }
2077
2078 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2079 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2080 return false;
2081 }
2082
2083 return true;
2084}
2085
David Benjamin1d128f32015-09-08 17:41:40 -04002086int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002087 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002088
Adam Langley10f97f32016-07-12 08:09:33 -07002089 if (!TestCipherRules() ||
2090 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2091 !TestSSL_SESSIONEncoding(kCustomSession) ||
2092 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2093 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2094 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2095 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002096 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002097 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2098 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2099 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2100 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2101 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2102 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2103 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2104 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2105 !TestCipherGetRFCName() ||
2106 !TestPaddingExtension() ||
2107 !TestClientCAList() ||
2108 !TestInternalSessionCache() ||
2109 !TestSequenceNumber(false /* TLS */) ||
2110 !TestSequenceNumber(true /* DTLS */) ||
2111 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002112 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002113 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002114 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002115 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002116 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002117 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002118 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002119 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002120 !TestSNICallback() ||
2121 !TestEarlyCallbackVersionSwitch()) {
Brian Smith83a82982015-04-09 16:21:10 -10002122 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002123 return 1;
2124 }
2125
David Benjamin2e521212014-07-16 14:37:51 -04002126 printf("PASS\n");
2127 return 0;
2128}