blob: 94551177458b198accd552346a28488c5eae44bb [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
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010059struct CurveTest {
60 // The rule string to apply.
61 const char *rule;
62 // The list of expected curves, in order.
63 std::vector<uint16_t> expected;
64};
65
David Benjaminfb974e62015-12-16 19:34:22 -050066static const CipherTest kCipherTests[] = {
67 // Selecting individual ciphers should work.
68 {
69 "ECDHE-ECDSA-CHACHA20-POLY1305:"
70 "ECDHE-RSA-CHACHA20-POLY1305:"
71 "ECDHE-ECDSA-AES128-GCM-SHA256:"
72 "ECDHE-RSA-AES128-GCM-SHA256",
73 {
74 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
75 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
76 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
77 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
78 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
80 },
81 },
82 // + reorders selected ciphers to the end, keeping their relative order.
83 {
84 "ECDHE-ECDSA-CHACHA20-POLY1305:"
85 "ECDHE-RSA-CHACHA20-POLY1305:"
86 "ECDHE-ECDSA-AES128-GCM-SHA256:"
87 "ECDHE-RSA-AES128-GCM-SHA256:"
88 "+aRSA",
89 {
90 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
91 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
92 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
96 },
97 },
98 // ! banishes ciphers from future selections.
99 {
100 "!aRSA:"
101 "ECDHE-ECDSA-CHACHA20-POLY1305:"
102 "ECDHE-RSA-CHACHA20-POLY1305:"
103 "ECDHE-ECDSA-AES128-GCM-SHA256:"
104 "ECDHE-RSA-AES128-GCM-SHA256",
105 {
106 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
107 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
108 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // Multiple masks can be ANDed in a single rule.
112 {
113 "kRSA+AESGCM+AES128",
114 {
115 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
117 },
118 // - removes selected ciphers, but preserves their order for future
119 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
120 // ECDHE_RSA.
121 {
122 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
123 "AESGCM+AES128+aRSA",
124 {
125 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
126 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Unknown selectors are no-ops.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256:"
136 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
139 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
140 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
144 },
145 },
146 // Square brackets specify equi-preference groups.
147 {
148 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
149 "[ECDHE-RSA-CHACHA20-POLY1305]:"
150 "ECDHE-RSA-AES128-GCM-SHA256",
151 {
152 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
153 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
157 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
158 },
159 },
160 // @STRENGTH performs a stable strength-sort of the selected ciphers and
161 // only the selected ciphers.
162 {
163 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700164 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500165 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
166 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500168 // Select ECDHE ones and sort them by strength. Ties should resolve
169 // based on the order above.
170 "kECDHE:@STRENGTH:-ALL:"
171 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
172 // by strength. Then RSA, backwards by strength.
173 "aRSA",
174 {
175 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
176 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
177 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500179 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
180 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
181 },
182 },
183 // Exact ciphers may not be used in multi-part rules; they are treated
184 // as unknown aliases.
185 {
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
189 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
194 },
195 // SSLv3 matches everything that existed before TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
200 },
201 },
202 // TLSv1.2 matches everything added in TLS 1.2.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 },
208 },
209 // The two directives have no intersection.
210 {
211 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
212 {
213 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
214 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
215 },
216 },
217 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
218 // name and not an alias. It may not be used in a multipart rule. (That the
219 // shared name works is covered by the standard tests.)
220 {
221 "ECDHE-ECDSA-CHACHA20-POLY1305:"
222 "ECDHE-RSA-CHACHA20-POLY1305:"
223 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
224 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
225 {
226 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
228 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
229 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
230 },
231 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232};
233
234static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
237 "RSA]",
238 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400244 "",
245 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400246 // COMPLEMENTOFDEFAULT is empty.
247 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400248 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400249 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400250 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400251 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
252 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
253 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400255};
256
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700257static const char *kMustNotIncludeNull[] = {
258 "ALL",
259 "DEFAULT",
260 "ALL:!eNULL",
261 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500262 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700263 "FIPS",
264 "SHA",
265 "SHA1",
266 "RSA",
267 "SSLv3",
268 "TLSv1",
269 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700270};
271
Matt Braithwaite053931e2016-05-25 12:06:05 -0700272static const char *kMustNotIncludeCECPQ1[] = {
273 "ALL",
274 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700275 "HIGH",
276 "FIPS",
277 "SHA",
278 "SHA1",
279 "SHA256",
280 "SHA384",
281 "RSA",
282 "SSLv3",
283 "TLSv1",
284 "TLSv1.2",
285 "aRSA",
286 "RSA",
287 "aECDSA",
288 "ECDSA",
289 "AES",
290 "AES128",
291 "AES256",
292 "AESGCM",
293 "CHACHA20",
294};
295
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100296static const CurveTest kCurveTests[] = {
297 {
298 "P-256",
299 { SSL_CURVE_SECP256R1 },
300 },
301 {
302 "P-256:P-384:P-521:X25519",
303 {
304 SSL_CURVE_SECP256R1,
305 SSL_CURVE_SECP384R1,
306 SSL_CURVE_SECP521R1,
307 SSL_CURVE_X25519,
308 },
309 },
310};
311
312static const char *kBadCurvesLists[] = {
313 "",
314 ":",
315 "::",
316 "P-256::X25519",
317 "RSA:P-256",
318 "P-256:RSA",
319 "X25519:P-256:",
320 ":X25519:P-256",
321};
322
David Benjamin1d77e562015-03-22 17:22:08 -0400323static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
324 bool in_group = false;
325 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400326 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
327 if (!in_group && list->in_group_flags[i]) {
328 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400329 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 }
331 fprintf(stderr, "\t");
332 if (in_group) {
333 fprintf(stderr, " ");
334 }
335 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
336 if (in_group && !list->in_group_flags[i]) {
337 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400338 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400339 }
340 }
341}
342
David Benjaminfb974e62015-12-16 19:34:22 -0500343static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700344 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400345 if (!ctx) {
346 return false;
David Benjamin65226252015-02-05 16:49:47 -0500347 }
348
David Benjaminfb974e62015-12-16 19:34:22 -0500349 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
350 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400351 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400352 }
353
David Benjamin1d77e562015-03-22 17:22:08 -0400354 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500355 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
356 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
357 PrintCipherPreferenceList(ctx->cipher_list);
358 return false;
359 }
360
361 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 const SSL_CIPHER *cipher =
363 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500364 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
365 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
366 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400367 PrintCipherPreferenceList(ctx->cipher_list);
368 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400369 }
370 }
371
David Benjamin1d77e562015-03-22 17:22:08 -0400372 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400373}
374
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700375static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700376 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700377 if (!ctx) {
378 return false;
379 }
380 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
381 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
382 return false;
383 }
384 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
385 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
386 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
387 return false;
388 }
389 }
390 return true;
391}
392
Matt Braithwaite053931e2016-05-25 12:06:05 -0700393static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700394 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700395 if (!ctx) {
396 return false;
397 }
398 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
399 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
400 return false;
401 }
402 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
403 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
404 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
405 return false;
406 }
407 }
408 return true;
409}
410
David Benjamin1d77e562015-03-22 17:22:08 -0400411static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500412 for (const CipherTest &test : kCipherTests) {
413 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400414 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400415 }
416 }
417
David Benjaminfb974e62015-12-16 19:34:22 -0500418 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700419 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400420 if (!ctx) {
421 return false;
David Benjamin65226252015-02-05 16:49:47 -0500422 }
David Benjaminfb974e62015-12-16 19:34:22 -0500423 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
424 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400425 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400426 }
427 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400428 }
429
David Benjaminfb974e62015-12-16 19:34:22 -0500430 for (const char *rule : kMustNotIncludeNull) {
431 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700432 return false;
433 }
434 }
435
Matt Braithwaite053931e2016-05-25 12:06:05 -0700436 for (const char *rule : kMustNotIncludeCECPQ1) {
437 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
438 return false;
439 }
440 }
441
David Benjamin1d77e562015-03-22 17:22:08 -0400442 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400443}
David Benjamin2e521212014-07-16 14:37:51 -0400444
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100445static bool TestCurveRule(const CurveTest &t) {
446 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
447 if (!ctx) {
448 return false;
449 }
450
451 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
452 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
453 return false;
454 }
455
456 // Compare the two lists.
457 if (ctx->supported_group_list_len != t.expected.size()) {
458 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
459 return false;
460 }
461
462 for (size_t i = 0; i < t.expected.size(); i++) {
463 if (t.expected[i] != ctx->supported_group_list[i]) {
464 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
465 return false;
466 }
467 }
468
469 return true;
470}
471
472static bool TestCurveRules() {
473 for (const CurveTest &test : kCurveTests) {
474 if (!TestCurveRule(test)) {
475 return false;
476 }
477 }
478
479 for (const char *rule : kBadCurvesLists) {
480 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
481 if (!ctx) {
482 return false;
483 }
484 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
485 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
486 return false;
487 }
488 ERR_clear_error();
489 }
490
491 return true;
492}
493
Adam Langley10f97f32016-07-12 08:09:33 -0700494// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
495// s_client -sess_out.
496static const char kOpenSSLSession[] =
497 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
498 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
499 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
500 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
501 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
502 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
503 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
504 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
505 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
506 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
507 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
508 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
509 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
510 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
511 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
512 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
513 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
514 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
515 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
516 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
517 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
518 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
519 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
520 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
521 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
522 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
523 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
524 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
525 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
526 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
527 "i4gv7Y5oliyn";
528
529// kCustomSession is a custom serialized SSL_SESSION generated by
530// filling in missing fields from |kOpenSSLSession|. This includes
531// providing |peer_sha256|, so |peer| is not serialized.
532static const char kCustomSession[] =
533 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
534 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
535 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
536 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
537 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
538 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
539 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
540 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
541
542// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
543static const char kBoringSSLSession[] =
544 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
545 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
546 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
547 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
548 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
549 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
550 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
551 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
552 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
553 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
554 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
555 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
556 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
557 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
558 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
559 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
560 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
561 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
562 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
563 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
564 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
565 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
566 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
567 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
568 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
569 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
570 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
571 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
572 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
573 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
574 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
575 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
576 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
577 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
578 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
579 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
580 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
581 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
582 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
583 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
584 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
585 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
586 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
587 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
588 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
589 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
590 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
591 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
592 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
593 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
594 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
595 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
596 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
597 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
598 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
599 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
600 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
601 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
602 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
603 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
604 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
605 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
606 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
607 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
608 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
609 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
610 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
611 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
612 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
613 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
614 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
615 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
616 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
617 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
618 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
619 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
620 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
621 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
622 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
623 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
624 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
625 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
626 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
627 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
628 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
629 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
630 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
631 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
632 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
633 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
634 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
635 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
636 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
637 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
638 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
639
640// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
641// the final (optional) element of |kCustomSession| with tag number 30.
642static const char kBadSessionExtraField[] =
643 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
644 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
645 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
646 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
647 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
648 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
649 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
650 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
651
652// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
653// the version of |kCustomSession| with 2.
654static const char kBadSessionVersion[] =
655 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
656 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
657 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
658 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
659 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
660 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
661 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
662 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
663
664// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
665// appended.
666static const char kBadSessionTrailingData[] =
667 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
668 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
669 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
670 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
671 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
672 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
673 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
674 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
675
David Benjamin1d77e562015-03-22 17:22:08 -0400676static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400677 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400678 if (!EVP_DecodedLength(&len, strlen(in))) {
679 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400680 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400681 }
682
David Benjamin1d77e562015-03-22 17:22:08 -0400683 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800684 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400685 strlen(in))) {
686 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400687 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400688 }
David Benjamin1d77e562015-03-22 17:22:08 -0400689 out->resize(len);
690 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400691}
692
David Benjamin1d77e562015-03-22 17:22:08 -0400693static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400694 const uint8_t *cptr;
695 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400696
David Benjamin1d77e562015-03-22 17:22:08 -0400697 // Decode the input.
698 std::vector<uint8_t> input;
699 if (!DecodeBase64(&input, input_b64)) {
700 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400701 }
702
David Benjamin1d77e562015-03-22 17:22:08 -0400703 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700704 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400705 if (!session) {
706 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400707 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400708 }
709
David Benjamin1d77e562015-03-22 17:22:08 -0400710 // Verify the SSL_SESSION encoding round-trips.
711 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700712 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400713 uint8_t *encoded_raw;
714 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400715 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400716 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400717 }
David Benjamin1d77e562015-03-22 17:22:08 -0400718 encoded.reset(encoded_raw);
719 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800720 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400721 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200722 hexdump(stderr, "Before: ", input.data(), input.size());
723 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400724 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400725 }
David Benjamin3cac4502014-10-21 01:46:30 -0400726
David Benjaminfd67aa82015-06-15 19:41:48 -0400727 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800728 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400729 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800730 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 fprintf(stderr, "d2i_SSL_SESSION failed\n");
732 return false;
733 }
734
David Benjamin1d77e562015-03-22 17:22:08 -0400735 // Verify the SSL_SESSION encoding round-trips via the legacy API.
736 int len = i2d_SSL_SESSION(session.get(), NULL);
737 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400738 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400739 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400740 }
741
David Benjamin1d77e562015-03-22 17:22:08 -0400742 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
743 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400744 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400745 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400746 }
David Benjamin1d77e562015-03-22 17:22:08 -0400747
748 ptr = encoded.get();
749 len = i2d_SSL_SESSION(session.get(), &ptr);
750 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400751 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400752 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400753 }
David Benjamin1d77e562015-03-22 17:22:08 -0400754 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400755 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400756 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400757 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800758 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400759 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400760 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400761 }
762
David Benjamin1d77e562015-03-22 17:22:08 -0400763 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400764}
765
David Benjaminf297e022015-05-28 19:55:29 -0400766static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
767 std::vector<uint8_t> input;
768 if (!DecodeBase64(&input, input_b64)) {
769 return false;
770 }
771
772 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700773 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400774 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400775 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400776 return false;
777 }
778 ERR_clear_error();
779 return true;
780}
781
David Benjamin10e664b2016-06-20 22:20:47 -0400782static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400783 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700784 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400785 if (!ctx) {
786 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500787 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400788 if (ctx->min_version != min_version || ctx->max_version != max_version) {
789 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
790 ctx->min_version, ctx->max_version, min_version, max_version);
791 return false;
792 }
793 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500794}
795
David Benjamin1d77e562015-03-22 17:22:08 -0400796static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500797 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
798 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400799 return false;
David Benjamin65226252015-02-05 16:49:47 -0500800 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700801 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400802 if (!rfc_name) {
803 return false;
804 }
David Benjamin67be0482015-04-20 16:19:00 -0400805 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400806 return true;
David Benjamin65226252015-02-05 16:49:47 -0500807}
808
809typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500810 int id;
David Benjamin65226252015-02-05 16:49:47 -0500811 const char *rfc_name;
812} CIPHER_RFC_NAME_TEST;
813
814static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500815 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500816 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500817 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
818 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
819 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500820 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
821 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
822 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
823 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
824 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
825 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
826 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
827 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
828 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
829 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
Adam Langley85bc5602015-06-09 09:54:04 -0700830 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
831 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500832 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
833 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400834 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000835 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500836 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000837 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500838 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500839};
840
David Benjamin1d77e562015-03-22 17:22:08 -0400841static bool TestCipherGetRFCName(void) {
842 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400843 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500844 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400845 std::string rfc_name;
846 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
847 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
848 return false;
David Benjamin65226252015-02-05 16:49:47 -0500849 }
David Benjamin1d77e562015-03-22 17:22:08 -0400850 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500851 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400852 rfc_name.c_str(), test->rfc_name);
853 return false;
David Benjamin65226252015-02-05 16:49:47 -0500854 }
David Benjamin65226252015-02-05 16:49:47 -0500855 }
David Benjamin1d77e562015-03-22 17:22:08 -0400856 return true;
David Benjamin65226252015-02-05 16:49:47 -0500857}
858
David Benjamin422fe082015-07-21 22:03:43 -0400859// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
860// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700861static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400862 std::vector<uint8_t> der;
863 if (!DecodeBase64(&der, kOpenSSLSession)) {
864 return nullptr;
865 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700866 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400867 if (!session) {
868 return nullptr;
869 }
870
871 // Swap out the ticket for a garbage one.
872 OPENSSL_free(session->tlsext_tick);
873 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
874 if (session->tlsext_tick == nullptr) {
875 return nullptr;
876 }
877 memset(session->tlsext_tick, 'a', ticket_len);
878 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400879
880 // Fix up the timeout.
881 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400882 return session;
883}
884
David Benjaminafc64de2016-07-19 17:12:41 +0200885static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700886 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200887 if (!bio) {
888 return false;
889 }
890 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400891 BIO_up_ref(bio.get());
892 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200893 int ret = SSL_connect(ssl);
894 if (ret > 0) {
895 // SSL_connect should fail without a BIO to write to.
896 return false;
897 }
898 ERR_clear_error();
899
900 const uint8_t *client_hello;
901 size_t client_hello_len;
902 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
903 return false;
904 }
905 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
906 return true;
907}
908
David Benjamin422fe082015-07-21 22:03:43 -0400909// GetClientHelloLen creates a client SSL connection with a ticket of length
910// |ticket_len| and records the ClientHello. It returns the length of the
911// ClientHello, not including the record header, on success and zero on error.
912static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700913 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
914 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400915 if (!ctx || !session) {
916 return 0;
917 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700918 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200919 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400920 return 0;
921 }
David Benjaminafc64de2016-07-19 17:12:41 +0200922 std::vector<uint8_t> client_hello;
923 if (!GetClientHello(ssl.get(), &client_hello) ||
924 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400925 return 0;
926 }
David Benjaminafc64de2016-07-19 17:12:41 +0200927 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400928}
929
930struct PaddingTest {
931 size_t input_len, padded_len;
932};
933
934static const PaddingTest kPaddingTests[] = {
935 // ClientHellos of length below 0x100 do not require padding.
936 {0xfe, 0xfe},
937 {0xff, 0xff},
938 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
939 {0x100, 0x200},
940 {0x123, 0x200},
941 {0x1fb, 0x200},
942 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
943 // padding extension takes a minimum of four bytes plus one required content
944 // byte. (To work around yet more server bugs, we avoid empty final
945 // extensions.)
946 {0x1fc, 0x201},
947 {0x1fd, 0x202},
948 {0x1fe, 0x203},
949 {0x1ff, 0x204},
950 // Finally, larger ClientHellos need no padding.
951 {0x200, 0x200},
952 {0x201, 0x201},
953};
954
955static bool TestPaddingExtension() {
956 // Sample a baseline length.
957 size_t base_len = GetClientHelloLen(1);
958 if (base_len == 0) {
959 return false;
960 }
961
962 for (const PaddingTest &test : kPaddingTests) {
963 if (base_len > test.input_len) {
964 fprintf(stderr, "Baseline ClientHello too long.\n");
965 return false;
966 }
967
968 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
969 if (padded_len != test.padded_len) {
970 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
971 static_cast<unsigned>(test.input_len),
972 static_cast<unsigned>(padded_len),
973 static_cast<unsigned>(test.padded_len));
974 return false;
975 }
976 }
977 return true;
978}
979
David Benjamin1d128f32015-09-08 17:41:40 -0400980// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
981// before configuring as a server.
982static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700983 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400984 if (!ctx) {
985 return false;
986 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700987 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400988 if (!ssl) {
989 return false;
990 }
991
992 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
993 if (stack == nullptr) {
994 return false;
995 }
996 // |SSL_set_client_CA_list| takes ownership.
997 SSL_set_client_CA_list(ssl.get(), stack);
998
999 return SSL_get_client_CA_list(ssl.get()) == stack;
1000}
1001
David Benjamin0f653952015-10-18 14:28:01 -04001002static void AppendSession(SSL_SESSION *session, void *arg) {
1003 std::vector<SSL_SESSION*> *out =
1004 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1005 out->push_back(session);
1006}
1007
1008// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1009// order.
1010static bool ExpectCache(SSL_CTX *ctx,
1011 const std::vector<SSL_SESSION*> &expected) {
1012 // Check the linked list.
1013 SSL_SESSION *ptr = ctx->session_cache_head;
1014 for (SSL_SESSION *session : expected) {
1015 if (ptr != session) {
1016 return false;
1017 }
1018 // TODO(davidben): This is an absurd way to denote the end of the list.
1019 if (ptr->next ==
1020 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1021 ptr = nullptr;
1022 } else {
1023 ptr = ptr->next;
1024 }
1025 }
1026 if (ptr != nullptr) {
1027 return false;
1028 }
1029
1030 // Check the hash table.
1031 std::vector<SSL_SESSION*> actual, expected_copy;
1032 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1033 expected_copy = expected;
1034
1035 std::sort(actual.begin(), actual.end());
1036 std::sort(expected_copy.begin(), expected_copy.end());
1037
1038 return actual == expected_copy;
1039}
1040
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001041static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1042 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001043 if (!ret) {
1044 return nullptr;
1045 }
1046
1047 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1048 memset(ret->session_id, 0, ret->session_id_length);
1049 memcpy(ret->session_id, &number, sizeof(number));
1050 return ret;
1051}
1052
David Benjamin0f653952015-10-18 14:28:01 -04001053// Test that the internal session cache behaves as expected.
1054static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001055 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001056 if (!ctx) {
1057 return false;
1058 }
1059
1060 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001061 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001062 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001063 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001064 if (!session) {
1065 return false;
1066 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001067 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001068 }
1069
1070 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1071
1072 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001073 for (const auto &session : sessions) {
1074 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001075 return false;
1076 }
1077 }
1078
1079 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001080 std::vector<SSL_SESSION*> expected = {
1081 sessions[9].get(),
1082 sessions[8].get(),
1083 sessions[7].get(),
1084 sessions[6].get(),
1085 sessions[5].get(),
1086 };
David Benjamin0f653952015-10-18 14:28:01 -04001087 if (!ExpectCache(ctx.get(), expected)) {
1088 return false;
1089 }
1090
1091 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001092 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001093 !ExpectCache(ctx.get(), expected)) {
1094 return false;
1095 }
1096
1097 // Although collisions should be impossible (256-bit session IDs), the cache
1098 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001099 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001100 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1101 return false;
1102 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001103 expected = {
1104 collision.get(),
1105 sessions[9].get(),
1106 sessions[8].get(),
1107 sessions[6].get(),
1108 sessions[5].get(),
1109 };
David Benjamin0f653952015-10-18 14:28:01 -04001110 if (!ExpectCache(ctx.get(), expected)) {
1111 return false;
1112 }
1113
1114 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001115 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001116 return false;
1117 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001118 expected = {
1119 collision.get(),
1120 sessions[9].get(),
1121 sessions[8].get(),
1122 sessions[5].get(),
1123 };
David Benjamin0f653952015-10-18 14:28:01 -04001124 if (!ExpectCache(ctx.get(), expected)) {
1125 return false;
1126 }
1127
1128 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001129 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1130 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001131 !ExpectCache(ctx.get(), expected)) {
1132 return false;
1133 }
1134
1135 return true;
1136}
1137
David Benjaminde942382016-02-11 12:02:01 -05001138static uint16_t EpochFromSequence(uint64_t seq) {
1139 return static_cast<uint16_t>(seq >> 48);
1140}
1141
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001142static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001143 static const char kCertPEM[] =
1144 "-----BEGIN CERTIFICATE-----\n"
1145 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1146 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1147 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1148 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1149 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1150 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1151 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1152 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1153 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1154 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1155 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1156 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1157 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1158 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001159 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1160 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001161}
1162
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001163static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001164 static const char kKeyPEM[] =
1165 "-----BEGIN RSA PRIVATE KEY-----\n"
1166 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1167 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1168 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1169 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1170 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1171 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1172 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1173 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1174 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1175 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1176 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1177 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1178 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1179 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001180 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1181 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001182 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1183}
1184
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001185static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001186 static const char kCertPEM[] =
1187 "-----BEGIN CERTIFICATE-----\n"
1188 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1189 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1190 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1191 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1192 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1193 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1194 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1195 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1196 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1197 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1198 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001199 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1200 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001201}
1202
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001203static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001204 static const char kKeyPEM[] =
1205 "-----BEGIN PRIVATE KEY-----\n"
1206 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1207 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1208 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1209 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001210 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1211 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001212 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1213}
1214
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001215static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001216 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1217 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001218 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001219 if (!client || !server) {
1220 return false;
1221 }
1222 SSL_set_connect_state(client.get());
1223 SSL_set_accept_state(server.get());
1224
David Benjamina20e5352016-08-02 19:09:41 -04001225 SSL_set_session(client.get(), session);
1226
David Benjaminde942382016-02-11 12:02:01 -05001227 BIO *bio1, *bio2;
1228 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1229 return false;
1230 }
1231 // SSL_set_bio takes ownership.
1232 SSL_set_bio(client.get(), bio1, bio1);
1233 SSL_set_bio(server.get(), bio2, bio2);
1234
1235 // Drive both their handshakes to completion.
1236 for (;;) {
1237 int client_ret = SSL_do_handshake(client.get());
1238 int client_err = SSL_get_error(client.get(), client_ret);
1239 if (client_err != SSL_ERROR_NONE &&
1240 client_err != SSL_ERROR_WANT_READ &&
1241 client_err != SSL_ERROR_WANT_WRITE) {
1242 fprintf(stderr, "Client error: %d\n", client_err);
1243 return false;
1244 }
1245
1246 int server_ret = SSL_do_handshake(server.get());
1247 int server_err = SSL_get_error(server.get(), server_ret);
1248 if (server_err != SSL_ERROR_NONE &&
1249 server_err != SSL_ERROR_WANT_READ &&
1250 server_err != SSL_ERROR_WANT_WRITE) {
1251 fprintf(stderr, "Server error: %d\n", server_err);
1252 return false;
1253 }
1254
1255 if (client_ret == 1 && server_ret == 1) {
1256 break;
1257 }
1258 }
1259
David Benjamin686bb192016-05-10 15:15:41 -04001260 *out_client = std::move(client);
1261 *out_server = std::move(server);
1262 return true;
1263}
1264
1265static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001266 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1267 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001268 if (!client_ctx || !server_ctx) {
1269 return false;
1270 }
1271
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001272 bssl::UniquePtr<X509> cert = GetTestCertificate();
1273 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001274 if (!cert || !key ||
1275 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1276 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1277 return false;
1278 }
1279
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001280 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001281 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001282 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001283 return false;
1284 }
1285
David Benjaminde942382016-02-11 12:02:01 -05001286 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1287 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1288 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1289 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1290
1291 if (dtls) {
1292 // Both client and server must be at epoch 1.
1293 if (EpochFromSequence(client_read_seq) != 1 ||
1294 EpochFromSequence(client_write_seq) != 1 ||
1295 EpochFromSequence(server_read_seq) != 1 ||
1296 EpochFromSequence(server_write_seq) != 1) {
1297 fprintf(stderr, "Bad epochs.\n");
1298 return false;
1299 }
1300
1301 // The next record to be written should exceed the largest received.
1302 if (client_write_seq <= server_read_seq ||
1303 server_write_seq <= client_read_seq) {
1304 fprintf(stderr, "Inconsistent sequence numbers.\n");
1305 return false;
1306 }
1307 } else {
1308 // The next record to be written should equal the next to be received.
1309 if (client_write_seq != server_read_seq ||
1310 server_write_seq != client_write_seq) {
1311 fprintf(stderr, "Inconsistent sequence numbers.\n");
1312 return false;
1313 }
1314 }
1315
1316 // Send a record from client to server.
1317 uint8_t byte = 0;
1318 if (SSL_write(client.get(), &byte, 1) != 1 ||
1319 SSL_read(server.get(), &byte, 1) != 1) {
1320 fprintf(stderr, "Could not send byte.\n");
1321 return false;
1322 }
1323
1324 // The client write and server read sequence numbers should have incremented.
1325 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1326 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1327 fprintf(stderr, "Sequence numbers did not increment.\n");\
1328 return false;
1329 }
1330
1331 return true;
1332}
1333
David Benjamin686bb192016-05-10 15:15:41 -04001334static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001335 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1336 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001337 if (!client_ctx || !server_ctx) {
1338 return false;
1339 }
1340
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001341 bssl::UniquePtr<X509> cert = GetTestCertificate();
1342 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001343 if (!cert || !key ||
1344 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1345 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1346 return false;
1347 }
1348
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001349 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001350 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001351 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001352 return false;
1353 }
1354
1355 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1356 // one side has shut down.
1357 if (SSL_shutdown(client.get()) != 0) {
1358 fprintf(stderr, "Could not shutdown.\n");
1359 return false;
1360 }
1361
1362 // Reading from the server should consume the EOF.
1363 uint8_t byte;
1364 if (SSL_read(server.get(), &byte, 1) != 0 ||
1365 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1366 fprintf(stderr, "Connection was not shut down cleanly.\n");
1367 return false;
1368 }
1369
1370 // However, the server may continue to write data and then shut down the
1371 // connection.
1372 byte = 42;
1373 if (SSL_write(server.get(), &byte, 1) != 1 ||
1374 SSL_read(client.get(), &byte, 1) != 1 ||
1375 byte != 42) {
1376 fprintf(stderr, "Could not send byte.\n");
1377 return false;
1378 }
1379
1380 // The server may then shutdown the connection.
1381 if (SSL_shutdown(server.get()) != 1 ||
1382 SSL_shutdown(client.get()) != 1) {
1383 fprintf(stderr, "Could not complete shutdown.\n");
1384 return false;
1385 }
1386
1387 return true;
1388}
Steven Valdez87eab492016-06-27 16:34:59 -04001389static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001390 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1391 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001392 if (!client_ctx || !server_ctx) {
1393 return false;
1394 }
1395
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001396 bssl::UniquePtr<X509> cert = GetTestCertificate();
1397 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001398 if (!cert || !key ||
1399 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1400 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1401 return false;
1402 }
1403
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001404 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001405 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001406 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001407 return false;
1408 }
1409
1410 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001411 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001412 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001413 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001414 }
David Benjamin4501bd52016-08-01 13:39:41 -04001415
Steven Valdez84b5c002016-08-25 16:30:58 -04001416 session1->not_resumable = 0;
1417
Steven Valdez87eab492016-06-27 16:34:59 -04001418 uint8_t *s0_bytes, *s1_bytes;
1419 size_t s0_len, s1_len;
1420
1421 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1422 return false;
1423 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001424 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001425
1426 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1427 return false;
1428 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001429 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001430
1431 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1432}
David Benjamin686bb192016-05-10 15:15:41 -04001433
David Benjamin5c0fb882016-06-14 14:03:51 -04001434static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1435 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1436 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1437 SSL_get_wfd(ssl), rfd, wfd);
1438 return false;
1439 }
1440
1441 // The wrapper BIOs are always equal when fds are equal, even if set
1442 // individually.
1443 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1444 fprintf(stderr, "rbio and wbio did not match.\n");
1445 return false;
1446 }
1447
1448 return true;
1449}
1450
1451static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001452 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001453 if (!ctx) {
1454 return false;
1455 }
1456
1457 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001458 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001459 if (!ssl ||
1460 !SSL_set_rfd(ssl.get(), 1) ||
1461 !SSL_set_wfd(ssl.get(), 2) ||
1462 !ExpectFDs(ssl.get(), 1, 2)) {
1463 return false;
1464 }
1465
1466 // Test setting the same FD.
1467 ssl.reset(SSL_new(ctx.get()));
1468 if (!ssl ||
1469 !SSL_set_fd(ssl.get(), 1) ||
1470 !ExpectFDs(ssl.get(), 1, 1)) {
1471 return false;
1472 }
1473
1474 // Test setting the same FD one side at a time.
1475 ssl.reset(SSL_new(ctx.get()));
1476 if (!ssl ||
1477 !SSL_set_rfd(ssl.get(), 1) ||
1478 !SSL_set_wfd(ssl.get(), 1) ||
1479 !ExpectFDs(ssl.get(), 1, 1)) {
1480 return false;
1481 }
1482
1483 // Test setting the same FD in the other order.
1484 ssl.reset(SSL_new(ctx.get()));
1485 if (!ssl ||
1486 !SSL_set_wfd(ssl.get(), 1) ||
1487 !SSL_set_rfd(ssl.get(), 1) ||
1488 !ExpectFDs(ssl.get(), 1, 1)) {
1489 return false;
1490 }
1491
David Benjamin5c0fb882016-06-14 14:03:51 -04001492 // Test changing the read FD partway through.
1493 ssl.reset(SSL_new(ctx.get()));
1494 if (!ssl ||
1495 !SSL_set_fd(ssl.get(), 1) ||
1496 !SSL_set_rfd(ssl.get(), 2) ||
1497 !ExpectFDs(ssl.get(), 2, 1)) {
1498 return false;
1499 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001500
1501 // Test changing the write FD partway through.
1502 ssl.reset(SSL_new(ctx.get()));
1503 if (!ssl ||
1504 !SSL_set_fd(ssl.get(), 1) ||
1505 !SSL_set_wfd(ssl.get(), 2) ||
1506 !ExpectFDs(ssl.get(), 1, 2)) {
1507 return false;
1508 }
1509
1510 // Test a no-op change to the read FD partway through.
1511 ssl.reset(SSL_new(ctx.get()));
1512 if (!ssl ||
1513 !SSL_set_fd(ssl.get(), 1) ||
1514 !SSL_set_rfd(ssl.get(), 1) ||
1515 !ExpectFDs(ssl.get(), 1, 1)) {
1516 return false;
1517 }
1518
1519 // Test a no-op change to the write FD partway through.
1520 ssl.reset(SSL_new(ctx.get()));
1521 if (!ssl ||
1522 !SSL_set_fd(ssl.get(), 1) ||
1523 !SSL_set_wfd(ssl.get(), 1) ||
1524 !ExpectFDs(ssl.get(), 1, 1)) {
1525 return false;
1526 }
1527
1528 // ASan builds will implicitly test that the internal |BIO| reference-counting
1529 // is correct.
1530
1531 return true;
1532}
1533
David Benjamin4501bd52016-08-01 13:39:41 -04001534static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001535 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001536 if (!ctx) {
1537 return false;
1538 }
1539
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001540 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1541 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001542 bio3(BIO_new(BIO_s_mem()));
1543 if (!ssl || !bio1 || !bio2 || !bio3) {
1544 return false;
1545 }
1546
1547 // SSL_set_bio takes one reference when the parameters are the same.
1548 BIO_up_ref(bio1.get());
1549 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1550
1551 // Repeating the call does nothing.
1552 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1553
1554 // It takes one reference each when the parameters are different.
1555 BIO_up_ref(bio2.get());
1556 BIO_up_ref(bio3.get());
1557 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1558
1559 // Repeating the call does nothing.
1560 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1561
1562 // It takes one reference when changing only wbio.
1563 BIO_up_ref(bio1.get());
1564 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1565
1566 // It takes one reference when changing only rbio and the two are different.
1567 BIO_up_ref(bio3.get());
1568 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1569
1570 // If setting wbio to rbio, it takes no additional references.
1571 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1572
1573 // From there, wbio may be switched to something else.
1574 BIO_up_ref(bio1.get());
1575 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1576
1577 // If setting rbio to wbio, it takes no additional references.
1578 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1579
1580 // From there, rbio may be switched to something else, but, for historical
1581 // reasons, it takes a reference to both parameters.
1582 BIO_up_ref(bio1.get());
1583 BIO_up_ref(bio2.get());
1584 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1585
1586 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1587 // is correct.
1588 return true;
1589}
1590
David Benjamincb18ac22016-09-27 14:09:15 -04001591static uint16_t kTLSVersions[] = {
David Benjamin25490f22016-07-14 00:22:54 -04001592 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1593};
1594
David Benjamincb18ac22016-09-27 14:09:15 -04001595static uint16_t kDTLSVersions[] = {
1596 DTLS1_VERSION, DTLS1_2_VERSION,
1597};
1598
David Benjamin25490f22016-07-14 00:22:54 -04001599static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1600
David Benjaminadd5e522016-07-14 00:33:24 -04001601static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001602 bssl::UniquePtr<X509> cert = GetTestCertificate();
1603 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001604 if (!cert || !key) {
1605 return false;
1606 }
1607
David Benjamincb18ac22016-09-27 14:09:15 -04001608 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001609 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001610 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001611 if (!ctx ||
1612 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001613 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001614 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1615 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001616 return false;
1617 }
David Benjaminadd5e522016-07-14 00:33:24 -04001618 SSL_CTX_set_verify(
1619 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1620 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1621
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001622 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001623 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1624 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001625 return false;
1626 }
1627
1628 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001629 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001630 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1631 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1632 return false;
1633 }
1634
1635 peer.reset(SSL_get_peer_certificate(client.get()));
1636 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1637 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1638 return false;
1639 }
1640
1641 // However, for historical reasons, the chain includes the leaf on the
1642 // client, but does not on the server.
1643 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1644 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1645 return false;
1646 }
1647
1648 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1649 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1650 return false;
1651 }
1652 }
1653
1654 return true;
1655}
1656
David Benjamin25490f22016-07-14 00:22:54 -04001657static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001658 bssl::UniquePtr<X509> cert = GetTestCertificate();
1659 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001660 if (!cert || !key) {
1661 return false;
1662 }
1663
1664 uint8_t *cert_der = NULL;
1665 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1666 if (cert_der_len < 0) {
1667 return false;
1668 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001669 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001670
1671 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1672 SHA256(cert_der, cert_der_len, cert_sha256);
1673
David Benjamincb18ac22016-09-27 14:09:15 -04001674 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001675 // Configure both client and server to accept any certificate, but the
1676 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001677 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001678 if (!ctx ||
1679 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001680 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001681 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1682 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001683 return false;
1684 }
David Benjamin25490f22016-07-14 00:22:54 -04001685 SSL_CTX_set_verify(
1686 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1687 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1688 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1689
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001690 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001691 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1692 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001693 return false;
1694 }
1695
1696 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001697 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001698 if (peer) {
1699 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1700 return false;
1701 }
1702
1703 SSL_SESSION *session = SSL_get_session(server.get());
1704 if (!session->peer_sha256_valid) {
1705 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1706 return false;
1707 }
1708
1709 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1710 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1711 return false;
1712 }
1713 }
1714
1715 return true;
1716}
1717
David Benjaminafc64de2016-07-19 17:12:41 +02001718static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1719 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001720 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001721 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001722 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001723 // Our default cipher list varies by CPU capabilities, so manually place
1724 // the ChaCha20 ciphers in front.
1725 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001726 return false;
1727 }
David Benjamin2dc02042016-09-19 19:57:37 -04001728
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001729 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001730 if (!ssl) {
1731 return false;
1732 }
1733 std::vector<uint8_t> client_hello;
1734 if (!GetClientHello(ssl.get(), &client_hello)) {
1735 return false;
1736 }
1737
1738 // Zero the client_random.
1739 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1740 1 + 3 + // handshake message header
1741 2; // client_version
1742 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1743 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1744 return false;
1745 }
1746 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1747
1748 if (client_hello.size() != expected_len ||
1749 memcmp(client_hello.data(), expected, expected_len) != 0) {
1750 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1751 fprintf(stderr, "Got:\n\t");
1752 for (size_t i = 0; i < client_hello.size(); i++) {
1753 fprintf(stderr, "0x%02x, ", client_hello[i]);
1754 }
1755 fprintf(stderr, "\nWanted:\n\t");
1756 for (size_t i = 0; i < expected_len; i++) {
1757 fprintf(stderr, "0x%02x, ", expected[i]);
1758 }
1759 fprintf(stderr, "\n");
1760 return false;
1761 }
1762
1763 return true;
1764}
1765
1766// Tests that our ClientHellos do not change unexpectedly.
1767static bool TestClientHello() {
1768 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001769 0x16,
1770 0x03, 0x00,
1771 0x00, 0x3f,
1772 0x01,
1773 0x00, 0x00, 0x3b,
1774 0x03, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00,
1780 0x00, 0x14,
1781 0xc0, 0x09,
1782 0xc0, 0x13,
1783 0x00, 0x33,
1784 0xc0, 0x0a,
1785 0xc0, 0x14,
1786 0x00, 0x39,
1787 0x00, 0x2f,
1788 0x00, 0x35,
1789 0x00, 0x0a,
1790 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001791 };
1792 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1793 sizeof(kSSL3ClientHello))) {
1794 return false;
1795 }
1796
1797 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001798 0x16,
1799 0x03, 0x01,
1800 0x00, 0x5e,
1801 0x01,
1802 0x00, 0x00, 0x5a,
1803 0x03, 0x01,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00,
1809 0x00, 0x12,
1810 0xc0, 0x09,
1811 0xc0, 0x13,
1812 0x00, 0x33,
1813 0xc0, 0x0a,
1814 0xc0, 0x14,
1815 0x00, 0x39,
1816 0x00, 0x2f,
1817 0x00, 0x35,
1818 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001819 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1820 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1821 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1822 };
1823 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1824 sizeof(kTLS1ClientHello))) {
1825 return false;
1826 }
1827
1828 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001829 0x16,
1830 0x03, 0x01,
1831 0x00, 0x5e,
1832 0x01,
1833 0x00, 0x00, 0x5a,
1834 0x03, 0x02,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00,
1840 0x00, 0x12,
1841 0xc0, 0x09,
1842 0xc0, 0x13,
1843 0x00, 0x33,
1844 0xc0, 0x0a,
1845 0xc0, 0x14,
1846 0x00, 0x39,
1847 0x00, 0x2f,
1848 0x00, 0x35,
1849 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001850 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1851 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1852 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1853 };
1854 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1855 sizeof(kTLS11ClientHello))) {
1856 return false;
1857 }
1858
1859 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001860 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1864 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1865 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1866 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1867 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1868 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1869 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjaminaf56fbd2016-09-21 14:38:06 -04001870 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
1871 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
David Benjamin57e929f2016-08-30 00:30:38 -04001872 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1873 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001874 };
1875 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1876 sizeof(kTLS12ClientHello))) {
1877 return false;
1878 }
1879
1880 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1881 // implementation has settled enough that it won't change.
1882
1883 return true;
1884}
1885
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001886static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001887
1888static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1889 // Save the most recent session.
1890 g_last_session.reset(session);
1891 return 1;
1892}
1893
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001894static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001895 SSL_CTX *server_ctx) {
1896 g_last_session = nullptr;
1897 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1898
1899 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001900 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001901 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1902 nullptr /* no session */)) {
1903 fprintf(stderr, "Failed to connect client and server.\n");
1904 return nullptr;
1905 }
1906
1907 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1908 SSL_read(client.get(), nullptr, 0);
1909
1910 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1911
1912 if (!g_last_session) {
1913 fprintf(stderr, "Client did not receive a session.\n");
1914 return nullptr;
1915 }
1916 return std::move(g_last_session);
1917}
1918
1919static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1920 SSL_SESSION *session,
1921 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001922 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001923 if (!ConnectClientAndServer(&client, &server, client_ctx,
1924 server_ctx, session)) {
1925 fprintf(stderr, "Failed to connect client and server.\n");
1926 return false;
1927 }
1928
1929 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1930 fprintf(stderr, "Client and server were inconsistent.\n");
1931 return false;
1932 }
1933
1934 bool was_reused = !!SSL_session_reused(client.get());
1935 if (was_reused != reused) {
1936 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1937 was_reused ? "" : " not");
1938 return false;
1939 }
1940
1941 return true;
1942}
1943
1944static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001945 bssl::UniquePtr<X509> cert = GetTestCertificate();
1946 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001947 if (!cert || !key) {
1948 return false;
1949 }
1950
1951 static const uint8_t kContext1[] = {1};
1952 static const uint8_t kContext2[] = {2};
1953
David Benjamincb18ac22016-09-27 14:09:15 -04001954 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001955 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1956 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001957 if (!server_ctx || !client_ctx ||
1958 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1959 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1960 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001961 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001962 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1963 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1964 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1965 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001966 return false;
1967 }
1968
David Benjamina20e5352016-08-02 19:09:41 -04001969 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04001970 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1971
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001972 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001973 CreateClientSession(client_ctx.get(), server_ctx.get());
1974 if (!session) {
1975 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1976 return false;
1977 }
1978
1979 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1980 true /* expect session reused */)) {
1981 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1982 return false;
1983 }
1984
1985 // Change the session ID context.
1986 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1987 sizeof(kContext2))) {
1988 return false;
1989 }
1990
1991 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1992 false /* expect session not reused */)) {
1993 fprintf(stderr,
1994 "Error connection with different context (version = %04x).\n",
1995 version);
1996 return false;
1997 }
1998 }
1999
2000 return true;
2001}
2002
David Benjamin721e8b72016-08-03 13:13:17 -04002003static timeval g_current_time;
2004
2005static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2006 *out_clock = g_current_time;
2007}
2008
2009static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002010 bssl::UniquePtr<X509> cert = GetTestCertificate();
2011 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002012 if (!cert || !key) {
2013 return false;
2014 }
2015
David Benjamincb18ac22016-09-27 14:09:15 -04002016 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002017 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2018 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04002019 if (!server_ctx || !client_ctx ||
2020 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002021 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002022 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2023 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2024 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2025 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamin721e8b72016-08-03 13:13:17 -04002026 return false;
2027 }
2028
David Benjamin721e8b72016-08-03 13:13:17 -04002029 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2030
David Benjamin721e8b72016-08-03 13:13:17 -04002031 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2032 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2033
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002034 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04002035 CreateClientSession(client_ctx.get(), server_ctx.get());
2036 if (!session) {
2037 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2038 return false;
2039 }
2040
2041 // Advance the clock just behind the timeout.
2042 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
2043
2044 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2045 true /* expect session reused */)) {
2046 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2047 return false;
2048 }
2049
2050 // Advance the clock one more second.
2051 g_current_time.tv_sec++;
2052
2053 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2054 false /* expect session not reused */)) {
2055 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2056 return false;
2057 }
2058 }
2059
2060 return true;
2061}
2062
David Benjamin0fc37ef2016-08-17 15:29:46 -04002063static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2064 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2065 SSL_set_SSL_CTX(ssl, ctx);
2066 return SSL_TLSEXT_ERR_OK;
2067}
2068
2069static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002070 bssl::UniquePtr<X509> cert = GetTestCertificate();
2071 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2072 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2073 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002074 if (!cert || !key || !cert2 || !key2) {
2075 return false;
2076 }
2077
2078 // At each version, test that switching the |SSL_CTX| at the SNI callback
2079 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002080 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002081 if (version == SSL3_VERSION) {
2082 continue;
2083 }
2084
2085 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2086
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002087 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2088 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2089 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002090 if (!server_ctx || !server_ctx2 || !client_ctx ||
2091 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2092 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2093 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2094 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2095 // Historically signing preferences would be lost in some cases with the
2096 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2097 // this doesn't happen when |version| is TLS 1.2, configure the private
2098 // key to only sign SHA-256.
2099 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002100 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002101 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2102 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2103 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2104 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2105 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2106 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002107 return false;
2108 }
2109
David Benjamin0fc37ef2016-08-17 15:29:46 -04002110 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2111 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2112
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002113 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002114 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2115 server_ctx.get(), nullptr)) {
2116 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2117 return false;
2118 }
2119
2120 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002121 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002122 if (!peer ||
2123 X509_cmp(peer.get(), cert2.get()) != 0) {
2124 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2125 version);
2126 return false;
2127 }
2128 }
2129
2130 return true;
2131}
2132
David Benjamin99620572016-08-30 00:35:36 -04002133static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002134 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002135 return -1;
2136 }
2137
David Benjamin99620572016-08-30 00:35:36 -04002138 return 1;
2139}
2140
2141// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2142// maximum version.
2143static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002144 bssl::UniquePtr<X509> cert = GetTestCertificate();
2145 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2146 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2147 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002148 if (!cert || !key || !server_ctx || !client_ctx ||
2149 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002150 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002151 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2152 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002153 return false;
2154 }
2155
David Benjamin99620572016-08-30 00:35:36 -04002156 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2157
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002158 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002159 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2160 server_ctx.get(), nullptr)) {
2161 return false;
2162 }
2163
2164 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2165 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2166 return false;
2167 }
2168
2169 return true;
2170}
2171
David Benjamin2dc02042016-09-19 19:57:37 -04002172static bool TestSetVersion() {
2173 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2174 if (!ctx) {
2175 return false;
2176 }
2177
David Benjamine4706902016-09-20 15:12:23 -04002178 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2179 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2180 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2181 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002182 fprintf(stderr, "Could not set valid TLS version.\n");
2183 return false;
2184 }
2185
David Benjamine4706902016-09-20 15:12:23 -04002186 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2187 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2188 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2189 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2190 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2191 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002192 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2193 return false;
2194 }
2195
David Benjamine34bcc92016-09-21 16:53:09 -04002196 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2197 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2198 fprintf(stderr, "Could not set default TLS version.\n");
2199 return false;
2200 }
2201
2202 if (ctx->min_version != SSL3_VERSION ||
2203 ctx->max_version != TLS1_2_VERSION) {
2204 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2205 ctx->min_version, ctx->max_version);
2206 return false;
2207 }
2208
David Benjamin2dc02042016-09-19 19:57:37 -04002209 ctx.reset(SSL_CTX_new(DTLS_method()));
2210 if (!ctx) {
2211 return false;
2212 }
2213
David Benjamine4706902016-09-20 15:12:23 -04002214 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2215 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2216 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2217 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002218 fprintf(stderr, "Could not set valid DTLS version.\n");
2219 return false;
2220 }
2221
David Benjamine4706902016-09-20 15:12:23 -04002222 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2223 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2224 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2225 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2226 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2227 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2228 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2229 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002230 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2231 return false;
2232 }
2233
David Benjamine34bcc92016-09-21 16:53:09 -04002234 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2235 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2236 fprintf(stderr, "Could not set default DTLS version.\n");
2237 return false;
2238 }
2239
2240 if (ctx->min_version != TLS1_1_VERSION ||
2241 ctx->max_version != TLS1_2_VERSION) {
2242 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2243 ctx->min_version, ctx->max_version);
2244 return false;
2245 }
2246
David Benjamin2dc02042016-09-19 19:57:37 -04002247 return true;
2248}
2249
David Benjamincb18ac22016-09-27 14:09:15 -04002250static bool TestVersions() {
2251 bssl::UniquePtr<X509> cert = GetTestCertificate();
2252 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2253 if (!cert || !key) {
2254 return false;
2255 }
2256
2257 for (bool is_dtls : std::vector<bool>{false, true}) {
2258 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2259 const char *name = is_dtls ? "DTLS" : "TLS";
2260 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2261 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2262 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2263 for (size_t i = 0; i < num_versions; i++) {
2264 uint16_t version = versions[i];
2265 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2266 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2267 bssl::UniquePtr<SSL> client, server;
2268 if (!server_ctx || !client_ctx ||
2269 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2270 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2271 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2272 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2273 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2274 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2275 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2276 server_ctx.get(), nullptr /* no session */)) {
2277 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2278 version);
2279 return false;
2280 }
2281
2282 if (SSL_version(client.get()) != version ||
2283 SSL_version(server.get()) != version) {
2284 fprintf(stderr,
2285 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2286 SSL_version(client.get()), SSL_version(server.get()), version);
2287 return false;
2288 }
2289 }
2290 }
2291
2292 return true;
2293}
2294
David Benjamin1d128f32015-09-08 17:41:40 -04002295int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002296 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002297
Adam Langley10f97f32016-07-12 08:09:33 -07002298 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002299 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002300 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2301 !TestSSL_SESSIONEncoding(kCustomSession) ||
2302 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2303 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2304 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2305 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002306 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002307 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2308 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2309 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2310 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2311 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2312 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2313 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2314 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2315 !TestCipherGetRFCName() ||
2316 !TestPaddingExtension() ||
2317 !TestClientCAList() ||
2318 !TestInternalSessionCache() ||
2319 !TestSequenceNumber(false /* TLS */) ||
2320 !TestSequenceNumber(true /* DTLS */) ||
2321 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002322 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002323 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002324 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002325 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002326 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002327 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002328 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002329 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002330 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002331 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002332 !TestSetVersion() ||
2333 !TestVersions()) {
Brian Smith83a82982015-04-09 16:21:10 -10002334 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002335 return 1;
2336 }
2337
David Benjamin2e521212014-07-16 14:37:51 -04002338 printf("PASS\n");
2339 return 0;
2340}