blob: 4ad513e7aa1cff4fb565e952a7df5f25b49dd437 [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 Benjamincb18ac22016-09-27 14:09:15 -04001508static uint16_t kTLSVersions[] = {
David Benjamin25490f22016-07-14 00:22:54 -04001509 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1510};
1511
David Benjamincb18ac22016-09-27 14:09:15 -04001512static uint16_t kDTLSVersions[] = {
1513 DTLS1_VERSION, DTLS1_2_VERSION,
1514};
1515
David Benjamin25490f22016-07-14 00:22:54 -04001516static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1517
David Benjaminadd5e522016-07-14 00:33:24 -04001518static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001519 bssl::UniquePtr<X509> cert = GetTestCertificate();
1520 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001521 if (!cert || !key) {
1522 return false;
1523 }
1524
David Benjamincb18ac22016-09-27 14:09:15 -04001525 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001526 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001527 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001528 if (!ctx ||
1529 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001530 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001531 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1532 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001533 return false;
1534 }
David Benjaminadd5e522016-07-14 00:33:24 -04001535 SSL_CTX_set_verify(
1536 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1537 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1538
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001539 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001540 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1541 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001542 return false;
1543 }
1544
1545 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001546 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001547 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1548 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1549 return false;
1550 }
1551
1552 peer.reset(SSL_get_peer_certificate(client.get()));
1553 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1554 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1555 return false;
1556 }
1557
1558 // However, for historical reasons, the chain includes the leaf on the
1559 // client, but does not on the server.
1560 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1561 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1562 return false;
1563 }
1564
1565 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1566 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1567 return false;
1568 }
1569 }
1570
1571 return true;
1572}
1573
David Benjamin25490f22016-07-14 00:22:54 -04001574static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001575 bssl::UniquePtr<X509> cert = GetTestCertificate();
1576 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001577 if (!cert || !key) {
1578 return false;
1579 }
1580
1581 uint8_t *cert_der = NULL;
1582 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1583 if (cert_der_len < 0) {
1584 return false;
1585 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001586 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001587
1588 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1589 SHA256(cert_der, cert_der_len, cert_sha256);
1590
David Benjamincb18ac22016-09-27 14:09:15 -04001591 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001592 // Configure both client and server to accept any certificate, but the
1593 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001594 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001595 if (!ctx ||
1596 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001597 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001598 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1599 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001600 return false;
1601 }
David Benjamin25490f22016-07-14 00:22:54 -04001602 SSL_CTX_set_verify(
1603 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1604 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1605 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1606
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001607 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001608 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1609 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001610 return false;
1611 }
1612
1613 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001614 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001615 if (peer) {
1616 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1617 return false;
1618 }
1619
1620 SSL_SESSION *session = SSL_get_session(server.get());
1621 if (!session->peer_sha256_valid) {
1622 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1623 return false;
1624 }
1625
1626 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1627 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1628 return false;
1629 }
1630 }
1631
1632 return true;
1633}
1634
David Benjaminafc64de2016-07-19 17:12:41 +02001635static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1636 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001637 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001638 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001639 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001640 // Our default cipher list varies by CPU capabilities, so manually place
1641 // the ChaCha20 ciphers in front.
1642 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001643 return false;
1644 }
David Benjamin2dc02042016-09-19 19:57:37 -04001645
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001646 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001647 if (!ssl) {
1648 return false;
1649 }
1650 std::vector<uint8_t> client_hello;
1651 if (!GetClientHello(ssl.get(), &client_hello)) {
1652 return false;
1653 }
1654
1655 // Zero the client_random.
1656 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1657 1 + 3 + // handshake message header
1658 2; // client_version
1659 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1660 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1661 return false;
1662 }
1663 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1664
1665 if (client_hello.size() != expected_len ||
1666 memcmp(client_hello.data(), expected, expected_len) != 0) {
1667 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1668 fprintf(stderr, "Got:\n\t");
1669 for (size_t i = 0; i < client_hello.size(); i++) {
1670 fprintf(stderr, "0x%02x, ", client_hello[i]);
1671 }
1672 fprintf(stderr, "\nWanted:\n\t");
1673 for (size_t i = 0; i < expected_len; i++) {
1674 fprintf(stderr, "0x%02x, ", expected[i]);
1675 }
1676 fprintf(stderr, "\n");
1677 return false;
1678 }
1679
1680 return true;
1681}
1682
1683// Tests that our ClientHellos do not change unexpectedly.
1684static bool TestClientHello() {
1685 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001686 0x16,
1687 0x03, 0x00,
1688 0x00, 0x3f,
1689 0x01,
1690 0x00, 0x00, 0x3b,
1691 0x03, 0x00,
1692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1696 0x00,
1697 0x00, 0x14,
1698 0xc0, 0x09,
1699 0xc0, 0x13,
1700 0x00, 0x33,
1701 0xc0, 0x0a,
1702 0xc0, 0x14,
1703 0x00, 0x39,
1704 0x00, 0x2f,
1705 0x00, 0x35,
1706 0x00, 0x0a,
1707 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001708 };
1709 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1710 sizeof(kSSL3ClientHello))) {
1711 return false;
1712 }
1713
1714 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001715 0x16,
1716 0x03, 0x01,
1717 0x00, 0x5e,
1718 0x01,
1719 0x00, 0x00, 0x5a,
1720 0x03, 0x01,
1721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1725 0x00,
1726 0x00, 0x12,
1727 0xc0, 0x09,
1728 0xc0, 0x13,
1729 0x00, 0x33,
1730 0xc0, 0x0a,
1731 0xc0, 0x14,
1732 0x00, 0x39,
1733 0x00, 0x2f,
1734 0x00, 0x35,
1735 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001736 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1737 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1738 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1739 };
1740 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1741 sizeof(kTLS1ClientHello))) {
1742 return false;
1743 }
1744
1745 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001746 0x16,
1747 0x03, 0x01,
1748 0x00, 0x5e,
1749 0x01,
1750 0x00, 0x00, 0x5a,
1751 0x03, 0x02,
1752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1756 0x00,
1757 0x00, 0x12,
1758 0xc0, 0x09,
1759 0xc0, 0x13,
1760 0x00, 0x33,
1761 0xc0, 0x0a,
1762 0xc0, 0x14,
1763 0x00, 0x39,
1764 0x00, 0x2f,
1765 0x00, 0x35,
1766 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001767 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1768 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1769 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1770 };
1771 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1772 sizeof(kTLS11ClientHello))) {
1773 return false;
1774 }
1775
1776 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001777 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1781 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1782 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1783 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1784 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1785 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1786 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjaminaf56fbd2016-09-21 14:38:06 -04001787 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
1788 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
David Benjamin57e929f2016-08-30 00:30:38 -04001789 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1790 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001791 };
1792 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1793 sizeof(kTLS12ClientHello))) {
1794 return false;
1795 }
1796
1797 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1798 // implementation has settled enough that it won't change.
1799
1800 return true;
1801}
1802
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001803static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001804
1805static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1806 // Save the most recent session.
1807 g_last_session.reset(session);
1808 return 1;
1809}
1810
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001811static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001812 SSL_CTX *server_ctx) {
1813 g_last_session = nullptr;
1814 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1815
1816 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001817 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001818 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1819 nullptr /* no session */)) {
1820 fprintf(stderr, "Failed to connect client and server.\n");
1821 return nullptr;
1822 }
1823
1824 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1825 SSL_read(client.get(), nullptr, 0);
1826
1827 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1828
1829 if (!g_last_session) {
1830 fprintf(stderr, "Client did not receive a session.\n");
1831 return nullptr;
1832 }
1833 return std::move(g_last_session);
1834}
1835
1836static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1837 SSL_SESSION *session,
1838 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001839 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001840 if (!ConnectClientAndServer(&client, &server, client_ctx,
1841 server_ctx, session)) {
1842 fprintf(stderr, "Failed to connect client and server.\n");
1843 return false;
1844 }
1845
1846 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1847 fprintf(stderr, "Client and server were inconsistent.\n");
1848 return false;
1849 }
1850
1851 bool was_reused = !!SSL_session_reused(client.get());
1852 if (was_reused != reused) {
1853 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1854 was_reused ? "" : " not");
1855 return false;
1856 }
1857
1858 return true;
1859}
1860
1861static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001862 bssl::UniquePtr<X509> cert = GetTestCertificate();
1863 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001864 if (!cert || !key) {
1865 return false;
1866 }
1867
1868 static const uint8_t kContext1[] = {1};
1869 static const uint8_t kContext2[] = {2};
1870
David Benjamincb18ac22016-09-27 14:09:15 -04001871 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001872 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1873 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001874 if (!server_ctx || !client_ctx ||
1875 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1876 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1877 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001878 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001879 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1880 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1881 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1882 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001883 return false;
1884 }
1885
David Benjamina20e5352016-08-02 19:09:41 -04001886 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04001887 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1888
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001889 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001890 CreateClientSession(client_ctx.get(), server_ctx.get());
1891 if (!session) {
1892 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1893 return false;
1894 }
1895
1896 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1897 true /* expect session reused */)) {
1898 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1899 return false;
1900 }
1901
1902 // Change the session ID context.
1903 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1904 sizeof(kContext2))) {
1905 return false;
1906 }
1907
1908 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1909 false /* expect session not reused */)) {
1910 fprintf(stderr,
1911 "Error connection with different context (version = %04x).\n",
1912 version);
1913 return false;
1914 }
1915 }
1916
1917 return true;
1918}
1919
David Benjamin721e8b72016-08-03 13:13:17 -04001920static timeval g_current_time;
1921
1922static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1923 *out_clock = g_current_time;
1924}
1925
1926static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001927 bssl::UniquePtr<X509> cert = GetTestCertificate();
1928 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04001929 if (!cert || !key) {
1930 return false;
1931 }
1932
David Benjamincb18ac22016-09-27 14:09:15 -04001933 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001934 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1935 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04001936 if (!server_ctx || !client_ctx ||
1937 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001938 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001939 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1940 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1941 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1942 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamin721e8b72016-08-03 13:13:17 -04001943 return false;
1944 }
1945
David Benjamin721e8b72016-08-03 13:13:17 -04001946 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1947
David Benjamin721e8b72016-08-03 13:13:17 -04001948 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1949 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1950
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001951 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04001952 CreateClientSession(client_ctx.get(), server_ctx.get());
1953 if (!session) {
1954 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1955 return false;
1956 }
1957
1958 // Advance the clock just behind the timeout.
1959 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
1960
1961 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1962 true /* expect session reused */)) {
1963 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1964 return false;
1965 }
1966
1967 // Advance the clock one more second.
1968 g_current_time.tv_sec++;
1969
1970 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1971 false /* expect session not reused */)) {
1972 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1973 return false;
1974 }
1975 }
1976
1977 return true;
1978}
1979
David Benjamin0fc37ef2016-08-17 15:29:46 -04001980static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
1981 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
1982 SSL_set_SSL_CTX(ssl, ctx);
1983 return SSL_TLSEXT_ERR_OK;
1984}
1985
1986static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001987 bssl::UniquePtr<X509> cert = GetTestCertificate();
1988 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1989 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
1990 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04001991 if (!cert || !key || !cert2 || !key2) {
1992 return false;
1993 }
1994
1995 // At each version, test that switching the |SSL_CTX| at the SNI callback
1996 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04001997 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001998 if (version == SSL3_VERSION) {
1999 continue;
2000 }
2001
2002 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2003
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002004 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2005 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2006 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002007 if (!server_ctx || !server_ctx2 || !client_ctx ||
2008 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2009 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2010 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2011 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2012 // Historically signing preferences would be lost in some cases with the
2013 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2014 // this doesn't happen when |version| is TLS 1.2, configure the private
2015 // key to only sign SHA-256.
2016 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002017 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002018 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2019 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2020 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2021 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2022 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2023 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002024 return false;
2025 }
2026
David Benjamin0fc37ef2016-08-17 15:29:46 -04002027 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2028 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2029
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002030 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002031 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2032 server_ctx.get(), nullptr)) {
2033 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2034 return false;
2035 }
2036
2037 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002038 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002039 if (!peer ||
2040 X509_cmp(peer.get(), cert2.get()) != 0) {
2041 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2042 version);
2043 return false;
2044 }
2045 }
2046
2047 return true;
2048}
2049
David Benjamin99620572016-08-30 00:35:36 -04002050static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002051 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002052 return -1;
2053 }
2054
David Benjamin99620572016-08-30 00:35:36 -04002055 return 1;
2056}
2057
2058// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2059// maximum version.
2060static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002061 bssl::UniquePtr<X509> cert = GetTestCertificate();
2062 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2063 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2064 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002065 if (!cert || !key || !server_ctx || !client_ctx ||
2066 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002067 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002068 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2069 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002070 return false;
2071 }
2072
David Benjamin99620572016-08-30 00:35:36 -04002073 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2074
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002075 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002076 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2077 server_ctx.get(), nullptr)) {
2078 return false;
2079 }
2080
2081 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2082 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2083 return false;
2084 }
2085
2086 return true;
2087}
2088
David Benjamin2dc02042016-09-19 19:57:37 -04002089static bool TestSetVersion() {
2090 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2091 if (!ctx) {
2092 return false;
2093 }
2094
David Benjamine4706902016-09-20 15:12:23 -04002095 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2096 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2097 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2098 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002099 fprintf(stderr, "Could not set valid TLS version.\n");
2100 return false;
2101 }
2102
David Benjamine4706902016-09-20 15:12:23 -04002103 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2104 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2105 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2106 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2107 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2108 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002109 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2110 return false;
2111 }
2112
David Benjamine34bcc92016-09-21 16:53:09 -04002113 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2114 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2115 fprintf(stderr, "Could not set default TLS version.\n");
2116 return false;
2117 }
2118
2119 if (ctx->min_version != SSL3_VERSION ||
2120 ctx->max_version != TLS1_2_VERSION) {
2121 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2122 ctx->min_version, ctx->max_version);
2123 return false;
2124 }
2125
David Benjamin2dc02042016-09-19 19:57:37 -04002126 ctx.reset(SSL_CTX_new(DTLS_method()));
2127 if (!ctx) {
2128 return false;
2129 }
2130
David Benjamine4706902016-09-20 15:12:23 -04002131 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2132 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2133 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2134 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002135 fprintf(stderr, "Could not set valid DTLS version.\n");
2136 return false;
2137 }
2138
David Benjamine4706902016-09-20 15:12:23 -04002139 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2140 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2141 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2142 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2143 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2144 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2145 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2146 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002147 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2148 return false;
2149 }
2150
David Benjamine34bcc92016-09-21 16:53:09 -04002151 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2152 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2153 fprintf(stderr, "Could not set default DTLS version.\n");
2154 return false;
2155 }
2156
2157 if (ctx->min_version != TLS1_1_VERSION ||
2158 ctx->max_version != TLS1_2_VERSION) {
2159 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2160 ctx->min_version, ctx->max_version);
2161 return false;
2162 }
2163
David Benjamin2dc02042016-09-19 19:57:37 -04002164 return true;
2165}
2166
David Benjamincb18ac22016-09-27 14:09:15 -04002167static bool TestVersions() {
2168 bssl::UniquePtr<X509> cert = GetTestCertificate();
2169 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2170 if (!cert || !key) {
2171 return false;
2172 }
2173
2174 for (bool is_dtls : std::vector<bool>{false, true}) {
2175 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2176 const char *name = is_dtls ? "DTLS" : "TLS";
2177 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2178 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2179 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2180 for (size_t i = 0; i < num_versions; i++) {
2181 uint16_t version = versions[i];
2182 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2183 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2184 bssl::UniquePtr<SSL> client, server;
2185 if (!server_ctx || !client_ctx ||
2186 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2187 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2188 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2189 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2190 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2191 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2192 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2193 server_ctx.get(), nullptr /* no session */)) {
2194 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2195 version);
2196 return false;
2197 }
2198
2199 if (SSL_version(client.get()) != version ||
2200 SSL_version(server.get()) != version) {
2201 fprintf(stderr,
2202 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2203 SSL_version(client.get()), SSL_version(server.get()), version);
2204 return false;
2205 }
2206 }
2207 }
2208
2209 return true;
2210}
2211
David Benjamin1d128f32015-09-08 17:41:40 -04002212int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002213 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002214
Adam Langley10f97f32016-07-12 08:09:33 -07002215 if (!TestCipherRules() ||
2216 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2217 !TestSSL_SESSIONEncoding(kCustomSession) ||
2218 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2219 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2220 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2221 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002222 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002223 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2224 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2225 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2226 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2227 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2228 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2229 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2230 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2231 !TestCipherGetRFCName() ||
2232 !TestPaddingExtension() ||
2233 !TestClientCAList() ||
2234 !TestInternalSessionCache() ||
2235 !TestSequenceNumber(false /* TLS */) ||
2236 !TestSequenceNumber(true /* DTLS */) ||
2237 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002238 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002239 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002240 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002241 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002242 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002243 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002244 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002245 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002246 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002247 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002248 !TestSetVersion() ||
2249 !TestVersions()) {
Brian Smith83a82982015-04-09 16:21:10 -10002250 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002251 return 1;
2252 }
2253
David Benjamin2e521212014-07-16 14:37:51 -04002254 printf("PASS\n");
2255 return 0;
2256}