blob: 30c37e24223d02eb8de25ac527462faaf0d33152 [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 Benjamin3c51d9b2016-11-01 17:50:42 -040026#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040027#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040028#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040029#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050030#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040031#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040033#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050034#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035
Steven Valdez87eab492016-06-27 16:34:59 -040036#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040037#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020038#include "../crypto/test/test_util.h"
39
David Benjamin721e8b72016-08-03 13:13:17 -040040#if defined(OPENSSL_WINDOWS)
41/* Windows defines struct timeval in winsock2.h. */
42OPENSSL_MSVC_PRAGMA(warning(push, 3))
43#include <winsock2.h>
44OPENSSL_MSVC_PRAGMA(warning(pop))
45#else
46#include <sys/time.h>
47#endif
48
David Benjamin1d77e562015-03-22 17:22:08 -040049
50struct ExpectedCipher {
51 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040052 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040053};
David Benjaminbb0a17c2014-09-20 15:35:39 -040054
David Benjamin1d77e562015-03-22 17:22:08 -040055struct CipherTest {
56 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040057 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050058 // The list of expected ciphers, in order.
59 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040060};
David Benjaminbb0a17c2014-09-20 15:35:39 -040061
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010062struct CurveTest {
63 // The rule string to apply.
64 const char *rule;
65 // The list of expected curves, in order.
66 std::vector<uint16_t> expected;
67};
68
David Benjaminfb974e62015-12-16 19:34:22 -050069static const CipherTest kCipherTests[] = {
70 // Selecting individual ciphers should work.
71 {
72 "ECDHE-ECDSA-CHACHA20-POLY1305:"
73 "ECDHE-RSA-CHACHA20-POLY1305:"
74 "ECDHE-ECDSA-AES128-GCM-SHA256:"
75 "ECDHE-RSA-AES128-GCM-SHA256",
76 {
77 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
78 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
80 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
81 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
82 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
83 },
84 },
85 // + reorders selected ciphers to the end, keeping their relative order.
86 {
87 "ECDHE-ECDSA-CHACHA20-POLY1305:"
88 "ECDHE-RSA-CHACHA20-POLY1305:"
89 "ECDHE-ECDSA-AES128-GCM-SHA256:"
90 "ECDHE-RSA-AES128-GCM-SHA256:"
91 "+aRSA",
92 {
93 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
96 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
97 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
98 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
99 },
100 },
101 // ! banishes ciphers from future selections.
102 {
103 "!aRSA:"
104 "ECDHE-ECDSA-CHACHA20-POLY1305:"
105 "ECDHE-RSA-CHACHA20-POLY1305:"
106 "ECDHE-ECDSA-AES128-GCM-SHA256:"
107 "ECDHE-RSA-AES128-GCM-SHA256",
108 {
109 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
110 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
111 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
112 },
113 },
114 // Multiple masks can be ANDed in a single rule.
115 {
116 "kRSA+AESGCM+AES128",
117 {
118 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
119 },
120 },
121 // - removes selected ciphers, but preserves their order for future
122 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
123 // ECDHE_RSA.
124 {
125 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
126 "AESGCM+AES128+aRSA",
127 {
128 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
129 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
130 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
131 },
132 },
133 // Unknown selectors are no-ops.
134 {
135 "ECDHE-ECDSA-CHACHA20-POLY1305:"
136 "ECDHE-RSA-CHACHA20-POLY1305:"
137 "ECDHE-ECDSA-AES128-GCM-SHA256:"
138 "ECDHE-RSA-AES128-GCM-SHA256:"
139 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
140 {
141 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
142 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
144 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
145 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
146 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
147 },
148 },
149 // Square brackets specify equi-preference groups.
150 {
151 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
152 "[ECDHE-RSA-CHACHA20-POLY1305]:"
153 "ECDHE-RSA-AES128-GCM-SHA256",
154 {
155 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
157 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
158 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
159 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
160 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
161 },
162 },
163 // @STRENGTH performs a stable strength-sort of the selected ciphers and
164 // only the selected ciphers.
165 {
166 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500168 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
169 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700170 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500171 // Select ECDHE ones and sort them by strength. Ties should resolve
172 // based on the order above.
173 "kECDHE:@STRENGTH:-ALL:"
174 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
175 // by strength. Then RSA, backwards by strength.
176 "aRSA",
177 {
178 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
179 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
180 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500181 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500182 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
183 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
184 },
185 },
186 // Exact ciphers may not be used in multi-part rules; they are treated
187 // as unknown aliases.
188 {
189 "ECDHE-ECDSA-AES128-GCM-SHA256:"
190 "ECDHE-RSA-AES128-GCM-SHA256:"
191 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
192 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
193 {
194 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
195 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
196 },
197 },
198 // SSLv3 matches everything that existed before TLS 1.2.
199 {
200 "AES128-SHA:AES128-SHA256:!SSLv3",
201 {
202 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
203 },
204 },
205 // TLSv1.2 matches everything added in TLS 1.2.
206 {
207 "AES128-SHA:AES128-SHA256:!TLSv1.2",
208 {
209 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
210 },
211 },
212 // The two directives have no intersection.
213 {
214 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
215 {
216 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
217 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
218 },
219 },
220 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
221 // name and not an alias. It may not be used in a multipart rule. (That the
222 // shared name works is covered by the standard tests.)
223 {
224 "ECDHE-ECDSA-CHACHA20-POLY1305:"
225 "ECDHE-RSA-CHACHA20-POLY1305:"
226 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
227 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
228 {
229 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
230 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
231 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
232 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
233 },
234 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235};
236
237static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400238 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400239 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
240 "RSA]",
241 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400242 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400243 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400244 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400245 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400246 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400247 "",
248 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400249 // COMPLEMENTOFDEFAULT is empty.
250 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400251 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400252 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400253 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
255 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
256 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
257 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700258 // Opcode supplied, but missing selector.
259 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400260};
261
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700262static const char *kMustNotIncludeNull[] = {
263 "ALL",
264 "DEFAULT",
265 "ALL:!eNULL",
266 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500267 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700268 "FIPS",
269 "SHA",
270 "SHA1",
271 "RSA",
272 "SSLv3",
273 "TLSv1",
274 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700275};
276
Matt Braithwaite053931e2016-05-25 12:06:05 -0700277static const char *kMustNotIncludeCECPQ1[] = {
278 "ALL",
279 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700280 "HIGH",
281 "FIPS",
282 "SHA",
283 "SHA1",
284 "SHA256",
285 "SHA384",
286 "RSA",
287 "SSLv3",
288 "TLSv1",
289 "TLSv1.2",
290 "aRSA",
291 "RSA",
292 "aECDSA",
293 "ECDSA",
294 "AES",
295 "AES128",
296 "AES256",
297 "AESGCM",
298 "CHACHA20",
299};
300
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100301static const CurveTest kCurveTests[] = {
302 {
303 "P-256",
304 { SSL_CURVE_SECP256R1 },
305 },
306 {
307 "P-256:P-384:P-521:X25519",
308 {
309 SSL_CURVE_SECP256R1,
310 SSL_CURVE_SECP384R1,
311 SSL_CURVE_SECP521R1,
312 SSL_CURVE_X25519,
313 },
314 },
315};
316
317static const char *kBadCurvesLists[] = {
318 "",
319 ":",
320 "::",
321 "P-256::X25519",
322 "RSA:P-256",
323 "P-256:RSA",
324 "X25519:P-256:",
325 ":X25519:P-256",
326};
327
David Benjamin1d77e562015-03-22 17:22:08 -0400328static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
329 bool in_group = false;
330 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400331 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
332 if (!in_group && list->in_group_flags[i]) {
333 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400334 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400335 }
336 fprintf(stderr, "\t");
337 if (in_group) {
338 fprintf(stderr, " ");
339 }
340 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
341 if (in_group && !list->in_group_flags[i]) {
342 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400343 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400344 }
345 }
346}
347
David Benjaminfb974e62015-12-16 19:34:22 -0500348static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700349 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400350 if (!ctx) {
351 return false;
David Benjamin65226252015-02-05 16:49:47 -0500352 }
353
David Benjaminfb974e62015-12-16 19:34:22 -0500354 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
355 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400356 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400357 }
358
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500360 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
361 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
362 PrintCipherPreferenceList(ctx->cipher_list);
363 return false;
364 }
365
366 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400367 const SSL_CIPHER *cipher =
368 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500369 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
370 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
371 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400372 PrintCipherPreferenceList(ctx->cipher_list);
373 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400374 }
375 }
376
David Benjamin1d77e562015-03-22 17:22:08 -0400377 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400378}
379
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700380static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700381 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700382 if (!ctx) {
383 return false;
384 }
385 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
386 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
387 return false;
388 }
389 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
390 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
391 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
392 return false;
393 }
394 }
395 return true;
396}
397
Matt Braithwaite053931e2016-05-25 12:06:05 -0700398static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700399 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700400 if (!ctx) {
401 return false;
402 }
403 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
404 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
405 return false;
406 }
407 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
408 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
409 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
410 return false;
411 }
412 }
413 return true;
414}
415
David Benjamin1d77e562015-03-22 17:22:08 -0400416static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500417 for (const CipherTest &test : kCipherTests) {
418 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400419 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400420 }
421 }
422
David Benjaminfb974e62015-12-16 19:34:22 -0500423 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700424 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400425 if (!ctx) {
426 return false;
David Benjamin65226252015-02-05 16:49:47 -0500427 }
David Benjaminfb974e62015-12-16 19:34:22 -0500428 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
429 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400430 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400431 }
432 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400433 }
434
David Benjaminfb974e62015-12-16 19:34:22 -0500435 for (const char *rule : kMustNotIncludeNull) {
436 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700437 return false;
438 }
439 }
440
Matt Braithwaite053931e2016-05-25 12:06:05 -0700441 for (const char *rule : kMustNotIncludeCECPQ1) {
442 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
443 return false;
444 }
445 }
446
David Benjamin1d77e562015-03-22 17:22:08 -0400447 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448}
David Benjamin2e521212014-07-16 14:37:51 -0400449
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100450static bool TestCurveRule(const CurveTest &t) {
451 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
452 if (!ctx) {
453 return false;
454 }
455
456 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
457 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
458 return false;
459 }
460
461 // Compare the two lists.
462 if (ctx->supported_group_list_len != t.expected.size()) {
463 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
464 return false;
465 }
466
467 for (size_t i = 0; i < t.expected.size(); i++) {
468 if (t.expected[i] != ctx->supported_group_list[i]) {
469 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
470 return false;
471 }
472 }
473
474 return true;
475}
476
477static bool TestCurveRules() {
478 for (const CurveTest &test : kCurveTests) {
479 if (!TestCurveRule(test)) {
480 return false;
481 }
482 }
483
484 for (const char *rule : kBadCurvesLists) {
485 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
486 if (!ctx) {
487 return false;
488 }
489 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
490 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
491 return false;
492 }
493 ERR_clear_error();
494 }
495
496 return true;
497}
498
Adam Langley10f97f32016-07-12 08:09:33 -0700499// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
500// s_client -sess_out.
501static const char kOpenSSLSession[] =
502 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
503 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
504 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
505 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
506 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
507 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
508 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
509 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
510 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
511 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
512 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
513 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
514 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
515 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
516 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
517 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
518 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
519 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
520 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
521 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
522 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
523 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
524 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
525 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
526 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
527 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
528 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
529 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
530 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
531 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
532 "i4gv7Y5oliyn";
533
534// kCustomSession is a custom serialized SSL_SESSION generated by
535// filling in missing fields from |kOpenSSLSession|. This includes
536// providing |peer_sha256|, so |peer| is not serialized.
537static const char kCustomSession[] =
538 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
539 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
540 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
541 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
542 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
543 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
544 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
545 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
546
547// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
548static const char kBoringSSLSession[] =
549 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
550 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
551 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
552 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
553 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
554 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
555 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
556 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
557 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
558 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
559 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
560 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
561 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
562 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
563 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
564 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
565 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
566 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
567 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
568 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
569 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
570 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
571 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
572 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
573 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
574 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
575 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
576 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
577 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
578 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
579 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
580 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
581 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
582 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
583 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
584 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
585 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
586 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
587 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
588 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
589 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
590 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
591 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
592 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
593 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
594 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
595 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
596 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
597 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
598 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
599 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
600 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
601 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
602 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
603 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
604 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
605 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
606 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
607 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
608 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
609 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
610 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
611 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
612 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
613 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
614 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
615 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
616 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
617 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
618 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
619 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
620 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
621 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
622 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
623 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
624 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
625 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
626 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
627 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
628 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
629 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
630 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
631 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
632 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
633 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
634 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
635 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
636 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
637 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
638 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
639 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
640 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
641 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
642 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
643 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
644
645// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
646// the final (optional) element of |kCustomSession| with tag number 30.
647static const char kBadSessionExtraField[] =
648 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
649 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
650 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
651 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
652 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
653 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
654 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
655 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
656
657// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
658// the version of |kCustomSession| with 2.
659static const char kBadSessionVersion[] =
660 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
661 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
662 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
663 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
664 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
665 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
666 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
667 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
668
669// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
670// appended.
671static const char kBadSessionTrailingData[] =
672 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
673 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
674 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
675 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
676 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
677 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
678 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
679 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
680
David Benjamin1d77e562015-03-22 17:22:08 -0400681static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400682 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400683 if (!EVP_DecodedLength(&len, strlen(in))) {
684 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400685 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400686 }
687
David Benjamin1d77e562015-03-22 17:22:08 -0400688 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800689 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400690 strlen(in))) {
691 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400692 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400693 }
David Benjamin1d77e562015-03-22 17:22:08 -0400694 out->resize(len);
695 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400696}
697
David Benjamin1d77e562015-03-22 17:22:08 -0400698static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400699 const uint8_t *cptr;
700 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400701
David Benjamin1d77e562015-03-22 17:22:08 -0400702 // Decode the input.
703 std::vector<uint8_t> input;
704 if (!DecodeBase64(&input, input_b64)) {
705 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400706 }
707
David Benjamin1d77e562015-03-22 17:22:08 -0400708 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700709 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400710 if (!session) {
711 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400712 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400713 }
714
David Benjamin1d77e562015-03-22 17:22:08 -0400715 // Verify the SSL_SESSION encoding round-trips.
716 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700717 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400718 uint8_t *encoded_raw;
719 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400720 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400721 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400722 }
David Benjamin1d77e562015-03-22 17:22:08 -0400723 encoded.reset(encoded_raw);
724 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800725 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400726 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200727 hexdump(stderr, "Before: ", input.data(), input.size());
728 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400729 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400730 }
David Benjamin3cac4502014-10-21 01:46:30 -0400731
David Benjaminfd67aa82015-06-15 19:41:48 -0400732 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800733 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400734 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800735 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400736 fprintf(stderr, "d2i_SSL_SESSION failed\n");
737 return false;
738 }
739
David Benjamin1d77e562015-03-22 17:22:08 -0400740 // Verify the SSL_SESSION encoding round-trips via the legacy API.
741 int len = i2d_SSL_SESSION(session.get(), NULL);
742 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400743 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400744 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400745 }
746
David Benjamin1d77e562015-03-22 17:22:08 -0400747 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
748 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400749 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400750 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400751 }
David Benjamin1d77e562015-03-22 17:22:08 -0400752
753 ptr = encoded.get();
754 len = i2d_SSL_SESSION(session.get(), &ptr);
755 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400756 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400757 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400758 }
David Benjamin1d77e562015-03-22 17:22:08 -0400759 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400760 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400761 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400762 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800763 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400764 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400765 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400766 }
767
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400769}
770
David Benjaminf297e022015-05-28 19:55:29 -0400771static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
772 std::vector<uint8_t> input;
773 if (!DecodeBase64(&input, input_b64)) {
774 return false;
775 }
776
777 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700778 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400779 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400780 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400781 return false;
782 }
783 ERR_clear_error();
784 return true;
785}
786
David Benjamin10e664b2016-06-20 22:20:47 -0400787static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400788 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700789 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400790 if (!ctx) {
791 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500792 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400793 if (ctx->min_version != min_version || ctx->max_version != max_version) {
794 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
795 ctx->min_version, ctx->max_version, min_version, max_version);
796 return false;
797 }
798 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500799}
800
David Benjamin1d77e562015-03-22 17:22:08 -0400801static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500802 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
803 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400804 return false;
David Benjamin65226252015-02-05 16:49:47 -0500805 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700806 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400807 if (!rfc_name) {
808 return false;
809 }
David Benjamin67be0482015-04-20 16:19:00 -0400810 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400811 return true;
David Benjamin65226252015-02-05 16:49:47 -0500812}
813
814typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500815 int id;
David Benjamin65226252015-02-05 16:49:47 -0500816 const char *rfc_name;
817} CIPHER_RFC_NAME_TEST;
818
819static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400820 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
821 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
822 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
823 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
824 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
825 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
826 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
827 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
828 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
829 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
830 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
831 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
832 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
833 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
834 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
835 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
836 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
837 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
838 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
839 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
840 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
841 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
842
843 // These names are non-standard:
844 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
845 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
846 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
847 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500848};
849
David Benjamin1d77e562015-03-22 17:22:08 -0400850static bool TestCipherGetRFCName(void) {
851 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400852 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500853 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400854 std::string rfc_name;
855 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
856 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
857 return false;
David Benjamin65226252015-02-05 16:49:47 -0500858 }
David Benjamin1d77e562015-03-22 17:22:08 -0400859 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500860 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400861 rfc_name.c_str(), test->rfc_name);
862 return false;
David Benjamin65226252015-02-05 16:49:47 -0500863 }
David Benjamin65226252015-02-05 16:49:47 -0500864 }
David Benjamin1d77e562015-03-22 17:22:08 -0400865 return true;
David Benjamin65226252015-02-05 16:49:47 -0500866}
867
David Benjamin422fe082015-07-21 22:03:43 -0400868// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
869// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700870static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400871 std::vector<uint8_t> der;
872 if (!DecodeBase64(&der, kOpenSSLSession)) {
873 return nullptr;
874 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700875 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400876 if (!session) {
877 return nullptr;
878 }
879
880 // Swap out the ticket for a garbage one.
881 OPENSSL_free(session->tlsext_tick);
882 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
883 if (session->tlsext_tick == nullptr) {
884 return nullptr;
885 }
886 memset(session->tlsext_tick, 'a', ticket_len);
887 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400888
889 // Fix up the timeout.
890 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400891 return session;
892}
893
David Benjaminafc64de2016-07-19 17:12:41 +0200894static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700895 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200896 if (!bio) {
897 return false;
898 }
899 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400900 BIO_up_ref(bio.get());
901 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200902 int ret = SSL_connect(ssl);
903 if (ret > 0) {
904 // SSL_connect should fail without a BIO to write to.
905 return false;
906 }
907 ERR_clear_error();
908
909 const uint8_t *client_hello;
910 size_t client_hello_len;
911 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
912 return false;
913 }
914 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
915 return true;
916}
917
David Benjamin422fe082015-07-21 22:03:43 -0400918// GetClientHelloLen creates a client SSL connection with a ticket of length
919// |ticket_len| and records the ClientHello. It returns the length of the
920// ClientHello, not including the record header, on success and zero on error.
921static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700922 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
923 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400924 if (!ctx || !session) {
925 return 0;
926 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700927 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400928 // Test at TLS 1.2. TLS 1.3 adds enough extensions that the ClientHello is
929 // longer than our test vectors.
930 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
931 !SSL_set_max_proto_version(ssl.get(), TLS1_2_VERSION)) {
David Benjamin422fe082015-07-21 22:03:43 -0400932 return 0;
933 }
David Benjaminafc64de2016-07-19 17:12:41 +0200934 std::vector<uint8_t> client_hello;
935 if (!GetClientHello(ssl.get(), &client_hello) ||
936 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400937 return 0;
938 }
David Benjaminafc64de2016-07-19 17:12:41 +0200939 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400940}
941
942struct PaddingTest {
943 size_t input_len, padded_len;
944};
945
946static const PaddingTest kPaddingTests[] = {
947 // ClientHellos of length below 0x100 do not require padding.
948 {0xfe, 0xfe},
949 {0xff, 0xff},
950 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
951 {0x100, 0x200},
952 {0x123, 0x200},
953 {0x1fb, 0x200},
954 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
955 // padding extension takes a minimum of four bytes plus one required content
956 // byte. (To work around yet more server bugs, we avoid empty final
957 // extensions.)
958 {0x1fc, 0x201},
959 {0x1fd, 0x202},
960 {0x1fe, 0x203},
961 {0x1ff, 0x204},
962 // Finally, larger ClientHellos need no padding.
963 {0x200, 0x200},
964 {0x201, 0x201},
965};
966
967static bool TestPaddingExtension() {
968 // Sample a baseline length.
969 size_t base_len = GetClientHelloLen(1);
970 if (base_len == 0) {
971 return false;
972 }
973
974 for (const PaddingTest &test : kPaddingTests) {
975 if (base_len > test.input_len) {
976 fprintf(stderr, "Baseline ClientHello too long.\n");
977 return false;
978 }
979
980 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
981 if (padded_len != test.padded_len) {
982 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
983 static_cast<unsigned>(test.input_len),
984 static_cast<unsigned>(padded_len),
985 static_cast<unsigned>(test.padded_len));
986 return false;
987 }
988 }
989 return true;
990}
991
David Benjamin1d128f32015-09-08 17:41:40 -0400992// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
993// before configuring as a server.
994static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700995 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400996 if (!ctx) {
997 return false;
998 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700999 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -04001000 if (!ssl) {
1001 return false;
1002 }
1003
1004 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
1005 if (stack == nullptr) {
1006 return false;
1007 }
1008 // |SSL_set_client_CA_list| takes ownership.
1009 SSL_set_client_CA_list(ssl.get(), stack);
1010
1011 return SSL_get_client_CA_list(ssl.get()) == stack;
1012}
1013
David Benjamin0f653952015-10-18 14:28:01 -04001014static void AppendSession(SSL_SESSION *session, void *arg) {
1015 std::vector<SSL_SESSION*> *out =
1016 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1017 out->push_back(session);
1018}
1019
1020// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1021// order.
1022static bool ExpectCache(SSL_CTX *ctx,
1023 const std::vector<SSL_SESSION*> &expected) {
1024 // Check the linked list.
1025 SSL_SESSION *ptr = ctx->session_cache_head;
1026 for (SSL_SESSION *session : expected) {
1027 if (ptr != session) {
1028 return false;
1029 }
1030 // TODO(davidben): This is an absurd way to denote the end of the list.
1031 if (ptr->next ==
1032 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1033 ptr = nullptr;
1034 } else {
1035 ptr = ptr->next;
1036 }
1037 }
1038 if (ptr != nullptr) {
1039 return false;
1040 }
1041
1042 // Check the hash table.
1043 std::vector<SSL_SESSION*> actual, expected_copy;
1044 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1045 expected_copy = expected;
1046
1047 std::sort(actual.begin(), actual.end());
1048 std::sort(expected_copy.begin(), expected_copy.end());
1049
1050 return actual == expected_copy;
1051}
1052
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001053static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1054 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001055 if (!ret) {
1056 return nullptr;
1057 }
1058
1059 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1060 memset(ret->session_id, 0, ret->session_id_length);
1061 memcpy(ret->session_id, &number, sizeof(number));
1062 return ret;
1063}
1064
David Benjamin0f653952015-10-18 14:28:01 -04001065// Test that the internal session cache behaves as expected.
1066static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001067 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001068 if (!ctx) {
1069 return false;
1070 }
1071
1072 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001073 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001074 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001075 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001076 if (!session) {
1077 return false;
1078 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001079 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001080 }
1081
1082 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1083
1084 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001085 for (const auto &session : sessions) {
1086 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001087 return false;
1088 }
1089 }
1090
1091 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001092 std::vector<SSL_SESSION*> expected = {
1093 sessions[9].get(),
1094 sessions[8].get(),
1095 sessions[7].get(),
1096 sessions[6].get(),
1097 sessions[5].get(),
1098 };
David Benjamin0f653952015-10-18 14:28:01 -04001099 if (!ExpectCache(ctx.get(), expected)) {
1100 return false;
1101 }
1102
1103 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001104 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001105 !ExpectCache(ctx.get(), expected)) {
1106 return false;
1107 }
1108
1109 // Although collisions should be impossible (256-bit session IDs), the cache
1110 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001111 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001112 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1113 return false;
1114 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001115 expected = {
1116 collision.get(),
1117 sessions[9].get(),
1118 sessions[8].get(),
1119 sessions[6].get(),
1120 sessions[5].get(),
1121 };
David Benjamin0f653952015-10-18 14:28:01 -04001122 if (!ExpectCache(ctx.get(), expected)) {
1123 return false;
1124 }
1125
1126 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001127 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001128 return false;
1129 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001130 expected = {
1131 collision.get(),
1132 sessions[9].get(),
1133 sessions[8].get(),
1134 sessions[5].get(),
1135 };
David Benjamin0f653952015-10-18 14:28:01 -04001136 if (!ExpectCache(ctx.get(), expected)) {
1137 return false;
1138 }
1139
1140 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001141 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1142 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001143 !ExpectCache(ctx.get(), expected)) {
1144 return false;
1145 }
1146
1147 return true;
1148}
1149
David Benjaminde942382016-02-11 12:02:01 -05001150static uint16_t EpochFromSequence(uint64_t seq) {
1151 return static_cast<uint16_t>(seq >> 48);
1152}
1153
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001154static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001155 static const char kCertPEM[] =
1156 "-----BEGIN CERTIFICATE-----\n"
1157 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1158 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1159 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1160 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1161 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1162 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1163 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1164 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1165 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1166 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1167 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1168 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1169 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1170 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001171 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1172 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001173}
1174
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001175static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001176 static const char kKeyPEM[] =
1177 "-----BEGIN RSA PRIVATE KEY-----\n"
1178 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1179 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1180 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1181 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1182 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1183 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1184 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1185 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1186 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1187 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1188 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1189 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1190 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1191 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001192 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1193 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001194 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1195}
1196
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001197static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001198 static const char kCertPEM[] =
1199 "-----BEGIN CERTIFICATE-----\n"
1200 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1201 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1202 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1203 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1204 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1205 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1206 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1207 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1208 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1209 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1210 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001211 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1212 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001213}
1214
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001215static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001216 static const char kKeyPEM[] =
1217 "-----BEGIN PRIVATE KEY-----\n"
1218 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1219 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1220 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1221 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001222 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1223 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001224 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1225}
1226
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001227static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001228 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1229 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001230 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001231 if (!client || !server) {
1232 return false;
1233 }
1234 SSL_set_connect_state(client.get());
1235 SSL_set_accept_state(server.get());
1236
David Benjamina20e5352016-08-02 19:09:41 -04001237 SSL_set_session(client.get(), session);
1238
David Benjaminde942382016-02-11 12:02:01 -05001239 BIO *bio1, *bio2;
1240 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1241 return false;
1242 }
1243 // SSL_set_bio takes ownership.
1244 SSL_set_bio(client.get(), bio1, bio1);
1245 SSL_set_bio(server.get(), bio2, bio2);
1246
1247 // Drive both their handshakes to completion.
1248 for (;;) {
1249 int client_ret = SSL_do_handshake(client.get());
1250 int client_err = SSL_get_error(client.get(), client_ret);
1251 if (client_err != SSL_ERROR_NONE &&
1252 client_err != SSL_ERROR_WANT_READ &&
1253 client_err != SSL_ERROR_WANT_WRITE) {
1254 fprintf(stderr, "Client error: %d\n", client_err);
1255 return false;
1256 }
1257
1258 int server_ret = SSL_do_handshake(server.get());
1259 int server_err = SSL_get_error(server.get(), server_ret);
1260 if (server_err != SSL_ERROR_NONE &&
1261 server_err != SSL_ERROR_WANT_READ &&
1262 server_err != SSL_ERROR_WANT_WRITE) {
1263 fprintf(stderr, "Server error: %d\n", server_err);
1264 return false;
1265 }
1266
1267 if (client_ret == 1 && server_ret == 1) {
1268 break;
1269 }
1270 }
1271
David Benjamin686bb192016-05-10 15:15:41 -04001272 *out_client = std::move(client);
1273 *out_server = std::move(server);
1274 return true;
1275}
1276
Steven Valdez2c62fe92016-10-14 12:08:12 -04001277static uint16_t kTLSVersions[] = {
1278 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1279};
David Benjamin686bb192016-05-10 15:15:41 -04001280
Steven Valdez2c62fe92016-10-14 12:08:12 -04001281static uint16_t kDTLSVersions[] = {
1282 DTLS1_VERSION, DTLS1_2_VERSION,
1283};
David Benjamin686bb192016-05-10 15:15:41 -04001284
Steven Valdez2c62fe92016-10-14 12:08:12 -04001285static bool TestSequenceNumber() {
1286 for (bool is_dtls : std::vector<bool>{false, true}) {
1287 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
1288 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
1289 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
1290 : OPENSSL_ARRAY_SIZE(kTLSVersions);
1291 for (size_t i = 0; i < num_versions; i++) {
1292 uint16_t version = versions[i];
1293 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1294 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1295 if (!server_ctx || !client_ctx ||
1296 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1297 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1298 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1299 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1300 return false;
1301 }
David Benjamin686bb192016-05-10 15:15:41 -04001302
Steven Valdez2c62fe92016-10-14 12:08:12 -04001303 bssl::UniquePtr<X509> cert = GetTestCertificate();
1304 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1305 if (!cert || !key ||
1306 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1307 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1308 return false;
1309 }
David Benjaminde942382016-02-11 12:02:01 -05001310
Steven Valdez2c62fe92016-10-14 12:08:12 -04001311 bssl::UniquePtr<SSL> client, server;
1312 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1313 server_ctx.get(), nullptr /* no session */)) {
1314 return false;
1315 }
1316
1317 // Drain any post-handshake messages to ensure there are no unread records
1318 // on either end.
1319 uint8_t byte = 0;
1320 if (SSL_read(client.get(), &byte, 1) > 0 ||
1321 SSL_read(server.get(), &byte, 1) > 0) {
1322 fprintf(stderr, "Received unexpected data.\n");
1323 return false;
1324 }
1325
1326 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1327 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1328 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1329 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1330
1331 if (is_dtls) {
1332 // Both client and server must be at epoch 1.
1333 if (EpochFromSequence(client_read_seq) != 1 ||
1334 EpochFromSequence(client_write_seq) != 1 ||
1335 EpochFromSequence(server_read_seq) != 1 ||
1336 EpochFromSequence(server_write_seq) != 1) {
1337 fprintf(stderr, "Bad epochs.\n");
1338 return false;
1339 }
1340
1341 // The next record to be written should exceed the largest received.
1342 if (client_write_seq <= server_read_seq ||
1343 server_write_seq <= client_read_seq) {
1344 fprintf(stderr, "Inconsistent sequence numbers.\n");
1345 return false;
1346 }
1347 } else {
1348 // The next record to be written should equal the next to be received.
1349 if (client_write_seq != server_read_seq ||
1350 server_write_seq != client_read_seq) {
1351 fprintf(stderr, "Inconsistent sequence numbers.\n");
1352 return false;
1353 }
1354 }
1355
1356 // Send a record from client to server.
1357 if (SSL_write(client.get(), &byte, 1) != 1 ||
1358 SSL_read(server.get(), &byte, 1) != 1) {
1359 fprintf(stderr, "Could not send byte.\n");
1360 return false;
1361 }
1362
1363 // The client write and server read sequence numbers should have
1364 // incremented.
1365 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1366 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1367 fprintf(stderr, "Sequence numbers did not increment.\n");
1368 return false;
1369 }
David Benjaminde942382016-02-11 12:02:01 -05001370 }
David Benjaminde942382016-02-11 12:02:01 -05001371 }
1372
1373 return true;
1374}
1375
David Benjamin686bb192016-05-10 15:15:41 -04001376static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001377 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1378 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001379 if (!client_ctx || !server_ctx) {
1380 return false;
1381 }
1382
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001383 bssl::UniquePtr<X509> cert = GetTestCertificate();
1384 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001385 if (!cert || !key ||
1386 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1387 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1388 return false;
1389 }
1390
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001391 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001392 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001393 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001394 return false;
1395 }
1396
1397 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1398 // one side has shut down.
1399 if (SSL_shutdown(client.get()) != 0) {
1400 fprintf(stderr, "Could not shutdown.\n");
1401 return false;
1402 }
1403
1404 // Reading from the server should consume the EOF.
1405 uint8_t byte;
1406 if (SSL_read(server.get(), &byte, 1) != 0 ||
1407 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1408 fprintf(stderr, "Connection was not shut down cleanly.\n");
1409 return false;
1410 }
1411
1412 // However, the server may continue to write data and then shut down the
1413 // connection.
1414 byte = 42;
1415 if (SSL_write(server.get(), &byte, 1) != 1 ||
1416 SSL_read(client.get(), &byte, 1) != 1 ||
1417 byte != 42) {
1418 fprintf(stderr, "Could not send byte.\n");
1419 return false;
1420 }
1421
1422 // The server may then shutdown the connection.
1423 if (SSL_shutdown(server.get()) != 1 ||
1424 SSL_shutdown(client.get()) != 1) {
1425 fprintf(stderr, "Could not complete shutdown.\n");
1426 return false;
1427 }
1428
1429 return true;
1430}
Steven Valdez87eab492016-06-27 16:34:59 -04001431static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001432 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1433 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001434 if (!client_ctx || !server_ctx) {
1435 return false;
1436 }
1437
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001438 bssl::UniquePtr<X509> cert = GetTestCertificate();
1439 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001440 if (!cert || !key ||
1441 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1442 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1443 return false;
1444 }
1445
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001446 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001447 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001448 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001449 return false;
1450 }
1451
1452 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001453 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001454 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001455 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001456 }
David Benjamin4501bd52016-08-01 13:39:41 -04001457
Steven Valdez84b5c002016-08-25 16:30:58 -04001458 session1->not_resumable = 0;
1459
Steven Valdez87eab492016-06-27 16:34:59 -04001460 uint8_t *s0_bytes, *s1_bytes;
1461 size_t s0_len, s1_len;
1462
1463 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1464 return false;
1465 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001466 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001467
1468 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1469 return false;
1470 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001471 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001472
1473 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1474}
David Benjamin686bb192016-05-10 15:15:41 -04001475
David Benjamin5c0fb882016-06-14 14:03:51 -04001476static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1477 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1478 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1479 SSL_get_wfd(ssl), rfd, wfd);
1480 return false;
1481 }
1482
1483 // The wrapper BIOs are always equal when fds are equal, even if set
1484 // individually.
1485 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1486 fprintf(stderr, "rbio and wbio did not match.\n");
1487 return false;
1488 }
1489
1490 return true;
1491}
1492
1493static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001494 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001495 if (!ctx) {
1496 return false;
1497 }
1498
1499 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001500 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001501 if (!ssl ||
1502 !SSL_set_rfd(ssl.get(), 1) ||
1503 !SSL_set_wfd(ssl.get(), 2) ||
1504 !ExpectFDs(ssl.get(), 1, 2)) {
1505 return false;
1506 }
1507
1508 // Test setting the same FD.
1509 ssl.reset(SSL_new(ctx.get()));
1510 if (!ssl ||
1511 !SSL_set_fd(ssl.get(), 1) ||
1512 !ExpectFDs(ssl.get(), 1, 1)) {
1513 return false;
1514 }
1515
1516 // Test setting the same FD one side at a time.
1517 ssl.reset(SSL_new(ctx.get()));
1518 if (!ssl ||
1519 !SSL_set_rfd(ssl.get(), 1) ||
1520 !SSL_set_wfd(ssl.get(), 1) ||
1521 !ExpectFDs(ssl.get(), 1, 1)) {
1522 return false;
1523 }
1524
1525 // Test setting the same FD in the other order.
1526 ssl.reset(SSL_new(ctx.get()));
1527 if (!ssl ||
1528 !SSL_set_wfd(ssl.get(), 1) ||
1529 !SSL_set_rfd(ssl.get(), 1) ||
1530 !ExpectFDs(ssl.get(), 1, 1)) {
1531 return false;
1532 }
1533
David Benjamin5c0fb882016-06-14 14:03:51 -04001534 // Test changing the read FD partway through.
1535 ssl.reset(SSL_new(ctx.get()));
1536 if (!ssl ||
1537 !SSL_set_fd(ssl.get(), 1) ||
1538 !SSL_set_rfd(ssl.get(), 2) ||
1539 !ExpectFDs(ssl.get(), 2, 1)) {
1540 return false;
1541 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001542
1543 // Test changing the write FD partway through.
1544 ssl.reset(SSL_new(ctx.get()));
1545 if (!ssl ||
1546 !SSL_set_fd(ssl.get(), 1) ||
1547 !SSL_set_wfd(ssl.get(), 2) ||
1548 !ExpectFDs(ssl.get(), 1, 2)) {
1549 return false;
1550 }
1551
1552 // Test a no-op change to the read FD partway through.
1553 ssl.reset(SSL_new(ctx.get()));
1554 if (!ssl ||
1555 !SSL_set_fd(ssl.get(), 1) ||
1556 !SSL_set_rfd(ssl.get(), 1) ||
1557 !ExpectFDs(ssl.get(), 1, 1)) {
1558 return false;
1559 }
1560
1561 // Test a no-op change to the write FD partway through.
1562 ssl.reset(SSL_new(ctx.get()));
1563 if (!ssl ||
1564 !SSL_set_fd(ssl.get(), 1) ||
1565 !SSL_set_wfd(ssl.get(), 1) ||
1566 !ExpectFDs(ssl.get(), 1, 1)) {
1567 return false;
1568 }
1569
1570 // ASan builds will implicitly test that the internal |BIO| reference-counting
1571 // is correct.
1572
1573 return true;
1574}
1575
David Benjamin4501bd52016-08-01 13:39:41 -04001576static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001577 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001578 if (!ctx) {
1579 return false;
1580 }
1581
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001582 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1583 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001584 bio3(BIO_new(BIO_s_mem()));
1585 if (!ssl || !bio1 || !bio2 || !bio3) {
1586 return false;
1587 }
1588
1589 // SSL_set_bio takes one reference when the parameters are the same.
1590 BIO_up_ref(bio1.get());
1591 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1592
1593 // Repeating the call does nothing.
1594 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1595
1596 // It takes one reference each when the parameters are different.
1597 BIO_up_ref(bio2.get());
1598 BIO_up_ref(bio3.get());
1599 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1600
1601 // Repeating the call does nothing.
1602 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1603
1604 // It takes one reference when changing only wbio.
1605 BIO_up_ref(bio1.get());
1606 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1607
1608 // It takes one reference when changing only rbio and the two are different.
1609 BIO_up_ref(bio3.get());
1610 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1611
1612 // If setting wbio to rbio, it takes no additional references.
1613 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1614
1615 // From there, wbio may be switched to something else.
1616 BIO_up_ref(bio1.get());
1617 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1618
1619 // If setting rbio to wbio, it takes no additional references.
1620 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1621
1622 // From there, rbio may be switched to something else, but, for historical
1623 // reasons, it takes a reference to both parameters.
1624 BIO_up_ref(bio1.get());
1625 BIO_up_ref(bio2.get());
1626 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1627
1628 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1629 // is correct.
1630 return true;
1631}
1632
David Benjamin25490f22016-07-14 00:22:54 -04001633static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1634
David Benjaminadd5e522016-07-14 00:33:24 -04001635static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001636 bssl::UniquePtr<X509> cert = GetTestCertificate();
1637 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001638 if (!cert || !key) {
1639 return false;
1640 }
1641
David Benjamincb18ac22016-09-27 14:09:15 -04001642 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001643 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001644 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001645 if (!ctx ||
1646 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001647 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001648 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1649 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001650 return false;
1651 }
David Benjaminadd5e522016-07-14 00:33:24 -04001652 SSL_CTX_set_verify(
1653 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1654 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1655
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001656 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001657 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1658 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001659 return false;
1660 }
1661
1662 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001663 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001664 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1665 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1666 return false;
1667 }
1668
1669 peer.reset(SSL_get_peer_certificate(client.get()));
1670 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1671 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1672 return false;
1673 }
1674
1675 // However, for historical reasons, the chain includes the leaf on the
1676 // client, but does not on the server.
1677 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1678 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1679 return false;
1680 }
1681
1682 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1683 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1684 return false;
1685 }
1686 }
1687
1688 return true;
1689}
1690
David Benjamin25490f22016-07-14 00:22:54 -04001691static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001692 bssl::UniquePtr<X509> cert = GetTestCertificate();
1693 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001694 if (!cert || !key) {
1695 return false;
1696 }
1697
1698 uint8_t *cert_der = NULL;
1699 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1700 if (cert_der_len < 0) {
1701 return false;
1702 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001703 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001704
1705 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1706 SHA256(cert_der, cert_der_len, cert_sha256);
1707
David Benjamincb18ac22016-09-27 14:09:15 -04001708 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001709 // Configure both client and server to accept any certificate, but the
1710 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001711 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001712 if (!ctx ||
1713 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001714 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001715 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1716 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001717 return false;
1718 }
David Benjamin25490f22016-07-14 00:22:54 -04001719 SSL_CTX_set_verify(
1720 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1721 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1722 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1723
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001724 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001725 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1726 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001727 return false;
1728 }
1729
1730 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001731 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001732 if (peer) {
1733 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1734 return false;
1735 }
1736
1737 SSL_SESSION *session = SSL_get_session(server.get());
1738 if (!session->peer_sha256_valid) {
1739 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1740 return false;
1741 }
1742
1743 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1744 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1745 return false;
1746 }
1747 }
1748
1749 return true;
1750}
1751
David Benjaminafc64de2016-07-19 17:12:41 +02001752static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1753 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001754 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001755 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001756 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001757 // Our default cipher list varies by CPU capabilities, so manually place
1758 // the ChaCha20 ciphers in front.
1759 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001760 return false;
1761 }
David Benjamin2dc02042016-09-19 19:57:37 -04001762
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001763 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001764 if (!ssl) {
1765 return false;
1766 }
1767 std::vector<uint8_t> client_hello;
1768 if (!GetClientHello(ssl.get(), &client_hello)) {
1769 return false;
1770 }
1771
1772 // Zero the client_random.
1773 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1774 1 + 3 + // handshake message header
1775 2; // client_version
1776 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1777 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1778 return false;
1779 }
1780 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1781
1782 if (client_hello.size() != expected_len ||
1783 memcmp(client_hello.data(), expected, expected_len) != 0) {
1784 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1785 fprintf(stderr, "Got:\n\t");
1786 for (size_t i = 0; i < client_hello.size(); i++) {
1787 fprintf(stderr, "0x%02x, ", client_hello[i]);
1788 }
1789 fprintf(stderr, "\nWanted:\n\t");
1790 for (size_t i = 0; i < expected_len; i++) {
1791 fprintf(stderr, "0x%02x, ", expected[i]);
1792 }
1793 fprintf(stderr, "\n");
1794 return false;
1795 }
1796
1797 return true;
1798}
1799
1800// Tests that our ClientHellos do not change unexpectedly.
1801static bool TestClientHello() {
1802 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001803 0x16,
1804 0x03, 0x00,
1805 0x00, 0x3f,
1806 0x01,
1807 0x00, 0x00, 0x3b,
1808 0x03, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00,
1814 0x00, 0x14,
1815 0xc0, 0x09,
1816 0xc0, 0x13,
1817 0x00, 0x33,
1818 0xc0, 0x0a,
1819 0xc0, 0x14,
1820 0x00, 0x39,
1821 0x00, 0x2f,
1822 0x00, 0x35,
1823 0x00, 0x0a,
1824 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001825 };
1826 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1827 sizeof(kSSL3ClientHello))) {
1828 return false;
1829 }
1830
1831 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001832 0x16,
1833 0x03, 0x01,
1834 0x00, 0x5e,
1835 0x01,
1836 0x00, 0x00, 0x5a,
1837 0x03, 0x01,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00,
1843 0x00, 0x12,
1844 0xc0, 0x09,
1845 0xc0, 0x13,
1846 0x00, 0x33,
1847 0xc0, 0x0a,
1848 0xc0, 0x14,
1849 0x00, 0x39,
1850 0x00, 0x2f,
1851 0x00, 0x35,
1852 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001853 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1854 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1855 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1856 };
1857 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1858 sizeof(kTLS1ClientHello))) {
1859 return false;
1860 }
1861
1862 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001863 0x16,
1864 0x03, 0x01,
1865 0x00, 0x5e,
1866 0x01,
1867 0x00, 0x00, 0x5a,
1868 0x03, 0x02,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1872 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1873 0x00,
1874 0x00, 0x12,
1875 0xc0, 0x09,
1876 0xc0, 0x13,
1877 0x00, 0x33,
1878 0xc0, 0x0a,
1879 0xc0, 0x14,
1880 0x00, 0x39,
1881 0x00, 0x2f,
1882 0x00, 0x35,
1883 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001884 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1885 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1886 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1887 };
1888 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1889 sizeof(kTLS11ClientHello))) {
1890 return false;
1891 }
1892
1893 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001894 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1898 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1899 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1900 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1901 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001902 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001903 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001904 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1905 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001906 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1907 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001908 };
1909 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1910 sizeof(kTLS12ClientHello))) {
1911 return false;
1912 }
1913
1914 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1915 // implementation has settled enough that it won't change.
1916
1917 return true;
1918}
1919
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001920static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001921
1922static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1923 // Save the most recent session.
1924 g_last_session.reset(session);
1925 return 1;
1926}
1927
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001928static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001929 SSL_CTX *server_ctx) {
1930 g_last_session = nullptr;
1931 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1932
1933 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001934 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001935 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1936 nullptr /* no session */)) {
1937 fprintf(stderr, "Failed to connect client and server.\n");
1938 return nullptr;
1939 }
1940
1941 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1942 SSL_read(client.get(), nullptr, 0);
1943
1944 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1945
1946 if (!g_last_session) {
1947 fprintf(stderr, "Client did not receive a session.\n");
1948 return nullptr;
1949 }
1950 return std::move(g_last_session);
1951}
1952
1953static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1954 SSL_SESSION *session,
1955 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001956 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001957 if (!ConnectClientAndServer(&client, &server, client_ctx,
1958 server_ctx, session)) {
1959 fprintf(stderr, "Failed to connect client and server.\n");
1960 return false;
1961 }
1962
1963 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1964 fprintf(stderr, "Client and server were inconsistent.\n");
1965 return false;
1966 }
1967
1968 bool was_reused = !!SSL_session_reused(client.get());
1969 if (was_reused != reused) {
1970 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1971 was_reused ? "" : " not");
1972 return false;
1973 }
1974
1975 return true;
1976}
1977
David Benjamin3c51d9b2016-11-01 17:50:42 -04001978static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
1979 SSL_CTX *server_ctx,
1980 SSL_SESSION *session) {
1981 g_last_session = nullptr;
1982 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1983
1984 bssl::UniquePtr<SSL> client, server;
1985 if (!ConnectClientAndServer(&client, &server, client_ctx,
1986 server_ctx, session)) {
1987 fprintf(stderr, "Failed to connect client and server.\n");
1988 return nullptr;
1989 }
1990
1991 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1992 fprintf(stderr, "Client and server were inconsistent.\n");
1993 return nullptr;
1994 }
1995
1996 if (!SSL_session_reused(client.get())) {
1997 fprintf(stderr, "Session was not reused.\n");
1998 return nullptr;
1999 }
2000
2001 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2002 SSL_read(client.get(), nullptr, 0);
2003
2004 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2005
2006 if (!g_last_session) {
2007 fprintf(stderr, "Client did not receive a renewed session.\n");
2008 return nullptr;
2009 }
2010 return std::move(g_last_session);
2011}
2012
David Benjamina20e5352016-08-02 19:09:41 -04002013static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002014 bssl::UniquePtr<X509> cert = GetTestCertificate();
2015 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002016 if (!cert || !key) {
2017 return false;
2018 }
2019
2020 static const uint8_t kContext1[] = {1};
2021 static const uint8_t kContext2[] = {2};
2022
David Benjamincb18ac22016-09-27 14:09:15 -04002023 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002024 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2025 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04002026 if (!server_ctx || !client_ctx ||
2027 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2028 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2029 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04002030 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04002031 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2032 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2033 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2034 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04002035 return false;
2036 }
2037
David Benjamina20e5352016-08-02 19:09:41 -04002038 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002039 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2040
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002041 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04002042 CreateClientSession(client_ctx.get(), server_ctx.get());
2043 if (!session) {
2044 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2045 return false;
2046 }
2047
2048 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2049 true /* expect session reused */)) {
2050 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2051 return false;
2052 }
2053
2054 // Change the session ID context.
2055 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2056 sizeof(kContext2))) {
2057 return false;
2058 }
2059
2060 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2061 false /* expect session not reused */)) {
2062 fprintf(stderr,
2063 "Error connection with different context (version = %04x).\n",
2064 version);
2065 return false;
2066 }
2067 }
2068
2069 return true;
2070}
2071
David Benjamin721e8b72016-08-03 13:13:17 -04002072static timeval g_current_time;
2073
2074static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2075 *out_clock = g_current_time;
2076}
2077
David Benjamin3c51d9b2016-11-01 17:50:42 -04002078static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2079 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2080 int encrypt) {
2081 static const uint8_t kZeros[16] = {0};
2082
2083 if (encrypt) {
2084 memcpy(key_name, kZeros, sizeof(kZeros));
2085 RAND_bytes(iv, 16);
2086 } else if (memcmp(key_name, kZeros, 16) != 0) {
2087 return 0;
2088 }
2089
2090 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2091 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2092 return -1;
2093 }
2094
2095 // Returning two from the callback in decrypt mode renews the
2096 // session in TLS 1.2 and below.
2097 return encrypt ? 1 : 2;
2098}
2099
David Benjamin721e8b72016-08-03 13:13:17 -04002100static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002101 bssl::UniquePtr<X509> cert = GetTestCertificate();
2102 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002103 if (!cert || !key) {
2104 return false;
2105 }
2106
David Benjamincb18ac22016-09-27 14:09:15 -04002107 for (uint16_t version : kTLSVersions) {
David Benjaminb2e2e322016-11-01 17:32:54 -04002108 for (bool server_test : std::vector<bool>{false, true}) {
2109 static const int kStartTime = 1000;
2110 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002111
David Benjaminb2e2e322016-11-01 17:32:54 -04002112 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2113 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2114 if (!server_ctx || !client_ctx ||
2115 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2116 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2117 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2118 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2119 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2120 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2121 return false;
2122 }
David Benjamin721e8b72016-08-03 13:13:17 -04002123
David Benjaminb2e2e322016-11-01 17:32:54 -04002124 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2125 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamin721e8b72016-08-03 13:13:17 -04002126
David Benjaminb2e2e322016-11-01 17:32:54 -04002127 // Both client and server must enforce session timeouts.
2128 if (server_test) {
2129 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2130 } else {
2131 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2132 }
David Benjamin721e8b72016-08-03 13:13:17 -04002133
David Benjamin3c51d9b2016-11-01 17:50:42 -04002134 // Configure a ticket callback which renews tickets.
2135 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2136
David Benjaminb2e2e322016-11-01 17:32:54 -04002137 bssl::UniquePtr<SSL_SESSION> session =
2138 CreateClientSession(client_ctx.get(), server_ctx.get());
2139 if (!session) {
2140 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2141 return false;
2142 }
David Benjamin721e8b72016-08-03 13:13:17 -04002143
David Benjaminb2e2e322016-11-01 17:32:54 -04002144 // Advance the clock just behind the timeout.
2145 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
David Benjamin721e8b72016-08-03 13:13:17 -04002146
David Benjaminb2e2e322016-11-01 17:32:54 -04002147 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2148 session.get(),
2149 true /* expect session reused */)) {
2150 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2151 return false;
2152 }
David Benjamin721e8b72016-08-03 13:13:17 -04002153
David Benjaminb2e2e322016-11-01 17:32:54 -04002154 // Advance the clock one more second.
2155 g_current_time.tv_sec++;
David Benjamin721e8b72016-08-03 13:13:17 -04002156
David Benjaminb2e2e322016-11-01 17:32:54 -04002157 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2158 session.get(),
2159 false /* expect session not reused */)) {
2160 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2161 return false;
2162 }
David Benjamin1b22f852016-10-27 16:36:32 -04002163
David Benjaminb2e2e322016-11-01 17:32:54 -04002164 // Rewind the clock to before the session was minted.
2165 g_current_time.tv_sec = kStartTime - 1;
David Benjamin1b22f852016-10-27 16:36:32 -04002166
David Benjaminb2e2e322016-11-01 17:32:54 -04002167 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2168 session.get(),
2169 false /* expect session not reused */)) {
2170 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2171 return false;
2172 }
David Benjamin3c51d9b2016-11-01 17:50:42 -04002173
2174 // SSL 3.0 cannot renew sessions.
2175 if (version == SSL3_VERSION) {
2176 continue;
2177 }
2178
2179 // Renew the session 10 seconds before expiration.
2180 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2181 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2182 client_ctx.get(), server_ctx.get(), session.get());
2183 if (!new_session) {
2184 fprintf(stderr, "Error renewing session (version = %04x).\n", version);
2185 return false;
2186 }
2187
2188 // This new session is not the same object as before.
2189 if (session.get() == new_session.get()) {
2190 fprintf(stderr, "New and old sessions alias (version = %04x).\n",
2191 version);
2192 return false;
2193 }
2194
2195 // The new session is usable just before the old expiration.
2196 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2197 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2198 new_session.get(),
2199 true /* expect session reused */)) {
2200 fprintf(stderr, "Error resuming renewed session (version = %04x).\n",
2201 version);
2202 return false;
2203 }
2204
2205 // Renewal does not extend the lifetime, so it is not usable beyond the
2206 // old expiration.
2207 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2208 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2209 new_session.get(),
2210 false /* expect session not reused */)) {
2211 fprintf(stderr,
2212 "Renewed session's lifetime is too long (version = %04x).\n",
2213 version);
2214 return false;
2215 }
David Benjamin1b22f852016-10-27 16:36:32 -04002216 }
David Benjamin721e8b72016-08-03 13:13:17 -04002217 }
2218
2219 return true;
2220}
2221
David Benjamin0fc37ef2016-08-17 15:29:46 -04002222static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2223 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2224 SSL_set_SSL_CTX(ssl, ctx);
2225 return SSL_TLSEXT_ERR_OK;
2226}
2227
2228static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002229 bssl::UniquePtr<X509> cert = GetTestCertificate();
2230 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2231 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2232 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002233 if (!cert || !key || !cert2 || !key2) {
2234 return false;
2235 }
2236
2237 // At each version, test that switching the |SSL_CTX| at the SNI callback
2238 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002239 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002240 if (version == SSL3_VERSION) {
2241 continue;
2242 }
2243
2244 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2245
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002246 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2247 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2248 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002249 if (!server_ctx || !server_ctx2 || !client_ctx ||
2250 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2251 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2252 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2253 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2254 // Historically signing preferences would be lost in some cases with the
2255 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2256 // this doesn't happen when |version| is TLS 1.2, configure the private
2257 // key to only sign SHA-256.
2258 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002259 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002260 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2261 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2262 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2263 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2264 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2265 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002266 return false;
2267 }
2268
David Benjamin0fc37ef2016-08-17 15:29:46 -04002269 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2270 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2271
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002272 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002273 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2274 server_ctx.get(), nullptr)) {
2275 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2276 return false;
2277 }
2278
2279 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002280 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002281 if (!peer ||
2282 X509_cmp(peer.get(), cert2.get()) != 0) {
2283 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2284 version);
2285 return false;
2286 }
2287 }
2288
2289 return true;
2290}
2291
David Benjamin99620572016-08-30 00:35:36 -04002292static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002293 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002294 return -1;
2295 }
2296
David Benjamin99620572016-08-30 00:35:36 -04002297 return 1;
2298}
2299
2300// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2301// maximum version.
2302static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002303 bssl::UniquePtr<X509> cert = GetTestCertificate();
2304 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2305 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2306 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002307 if (!cert || !key || !server_ctx || !client_ctx ||
2308 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002309 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002310 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2311 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002312 return false;
2313 }
2314
David Benjamin99620572016-08-30 00:35:36 -04002315 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2316
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002317 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002318 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2319 server_ctx.get(), nullptr)) {
2320 return false;
2321 }
2322
2323 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2324 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2325 return false;
2326 }
2327
2328 return true;
2329}
2330
David Benjamin2dc02042016-09-19 19:57:37 -04002331static bool TestSetVersion() {
2332 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2333 if (!ctx) {
2334 return false;
2335 }
2336
David Benjamine4706902016-09-20 15:12:23 -04002337 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2338 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2339 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2340 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002341 fprintf(stderr, "Could not set valid TLS version.\n");
2342 return false;
2343 }
2344
David Benjamine4706902016-09-20 15:12:23 -04002345 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2346 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2347 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2348 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2349 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2350 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002351 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2352 return false;
2353 }
2354
David Benjamine34bcc92016-09-21 16:53:09 -04002355 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2356 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2357 fprintf(stderr, "Could not set default TLS version.\n");
2358 return false;
2359 }
2360
2361 if (ctx->min_version != SSL3_VERSION ||
2362 ctx->max_version != TLS1_2_VERSION) {
2363 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2364 ctx->min_version, ctx->max_version);
2365 return false;
2366 }
2367
David Benjamin2dc02042016-09-19 19:57:37 -04002368 ctx.reset(SSL_CTX_new(DTLS_method()));
2369 if (!ctx) {
2370 return false;
2371 }
2372
David Benjamine4706902016-09-20 15:12:23 -04002373 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2374 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2375 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2376 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002377 fprintf(stderr, "Could not set valid DTLS version.\n");
2378 return false;
2379 }
2380
David Benjamine4706902016-09-20 15:12:23 -04002381 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2382 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2383 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2384 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2385 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2386 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2387 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2388 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002389 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2390 return false;
2391 }
2392
David Benjamine34bcc92016-09-21 16:53:09 -04002393 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2394 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2395 fprintf(stderr, "Could not set default DTLS version.\n");
2396 return false;
2397 }
2398
2399 if (ctx->min_version != TLS1_1_VERSION ||
2400 ctx->max_version != TLS1_2_VERSION) {
2401 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2402 ctx->min_version, ctx->max_version);
2403 return false;
2404 }
2405
David Benjamin2dc02042016-09-19 19:57:37 -04002406 return true;
2407}
2408
David Benjamincb18ac22016-09-27 14:09:15 -04002409static bool TestVersions() {
2410 bssl::UniquePtr<X509> cert = GetTestCertificate();
2411 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2412 if (!cert || !key) {
2413 return false;
2414 }
2415
2416 for (bool is_dtls : std::vector<bool>{false, true}) {
2417 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2418 const char *name = is_dtls ? "DTLS" : "TLS";
2419 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2420 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2421 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2422 for (size_t i = 0; i < num_versions; i++) {
2423 uint16_t version = versions[i];
2424 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2425 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2426 bssl::UniquePtr<SSL> client, server;
2427 if (!server_ctx || !client_ctx ||
2428 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2429 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2430 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2431 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2432 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2433 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2434 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2435 server_ctx.get(), nullptr /* no session */)) {
2436 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2437 version);
2438 return false;
2439 }
2440
2441 if (SSL_version(client.get()) != version ||
2442 SSL_version(server.get()) != version) {
2443 fprintf(stderr,
2444 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2445 SSL_version(client.get()), SSL_version(server.get()), version);
2446 return false;
2447 }
2448 }
2449 }
2450
2451 return true;
2452}
2453
David Benjamin9ef31f02016-10-31 18:01:13 -04002454// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2455// selection callback.
2456static bool TestALPNCipherAvailable() {
2457 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2458
2459 bssl::UniquePtr<X509> cert = GetTestCertificate();
2460 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2461 if (!cert || !key) {
2462 return false;
2463 }
2464
2465 for (uint16_t version : kTLSVersions) {
2466 // SSL 3.0 lacks extensions.
2467 if (version == SSL3_VERSION) {
2468 continue;
2469 }
2470
2471 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2472 if (!ctx ||
2473 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2474 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2475 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2476 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2477 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2478 0) {
2479 return false;
2480 }
2481
2482 // The ALPN callback does not fail the handshake on error, so have the
2483 // callback write a boolean.
Adam Langleyfb73e972016-11-02 13:21:29 -07002484 std::pair<uint16_t, bool> callback_state(version, false);
David Benjamin9ef31f02016-10-31 18:01:13 -04002485 SSL_CTX_set_alpn_select_cb(
2486 ctx.get(),
2487 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2488 unsigned in_len, void *arg) -> int {
Adam Langleyfb73e972016-11-02 13:21:29 -07002489 auto state = reinterpret_cast<std::pair<uint16_t, bool>*>(arg);
2490 if (SSL_get_pending_cipher(ssl) != nullptr &&
2491 SSL_version(ssl) == state->first) {
2492 state->second = true;
2493 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002494 return SSL_TLSEXT_ERR_NOACK;
2495 },
Adam Langleyfb73e972016-11-02 13:21:29 -07002496 &callback_state);
David Benjamin9ef31f02016-10-31 18:01:13 -04002497
2498 bssl::UniquePtr<SSL> client, server;
2499 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2500 nullptr /* no session */)) {
2501 return false;
2502 }
2503
Adam Langleyfb73e972016-11-02 13:21:29 -07002504 if (!callback_state.second) {
David Benjamin9ef31f02016-10-31 18:01:13 -04002505 fprintf(stderr,
2506 "%x: The pending cipher was not known in the ALPN callback.\n",
2507 version);
2508 return false;
2509 }
2510 }
2511
2512 return true;
2513}
2514
David Benjamin1d128f32015-09-08 17:41:40 -04002515int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002516 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002517
Adam Langley10f97f32016-07-12 08:09:33 -07002518 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002519 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002520 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2521 !TestSSL_SESSIONEncoding(kCustomSession) ||
2522 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2523 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2524 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2525 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002526 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002527 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2528 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2529 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2530 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2531 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2532 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2533 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2534 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2535 !TestCipherGetRFCName() ||
2536 !TestPaddingExtension() ||
2537 !TestClientCAList() ||
2538 !TestInternalSessionCache() ||
Steven Valdez2c62fe92016-10-14 12:08:12 -04002539 !TestSequenceNumber() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002540 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002541 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002542 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002543 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002544 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002545 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002546 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002547 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002548 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002549 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002550 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002551 !TestSetVersion() ||
David Benjamin9ef31f02016-10-31 18:01:13 -04002552 !TestVersions() ||
2553 !TestALPNCipherAvailable()) {
Brian Smith83a82982015-04-09 16:21:10 -10002554 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002555 return 1;
2556 }
2557
David Benjamin2e521212014-07-16 14:37:51 -04002558 printf("PASS\n");
2559 return 0;
2560}