blob: ed32c212d31eae16805502bcfd8a65122c6787b3 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040026#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040027#include <openssl/err.h>
David Benjaminde942382016-02-11 12:02:01 -050028#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040029#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050031#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032
Steven Valdez87eab492016-06-27 16:34:59 -040033#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040034#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020035#include "../crypto/test/test_util.h"
36
David Benjamin721e8b72016-08-03 13:13:17 -040037#if defined(OPENSSL_WINDOWS)
38/* Windows defines struct timeval in winsock2.h. */
39OPENSSL_MSVC_PRAGMA(warning(push, 3))
40#include <winsock2.h>
41OPENSSL_MSVC_PRAGMA(warning(pop))
42#else
43#include <sys/time.h>
44#endif
45
David Benjamin1d77e562015-03-22 17:22:08 -040046
47struct ExpectedCipher {
48 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040049 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040050};
David Benjaminbb0a17c2014-09-20 15:35:39 -040051
David Benjamin1d77e562015-03-22 17:22:08 -040052struct CipherTest {
53 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050055 // The list of expected ciphers, in order.
56 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040057};
David Benjaminbb0a17c2014-09-20 15:35:39 -040058
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010059struct CurveTest {
60 // The rule string to apply.
61 const char *rule;
62 // The list of expected curves, in order.
63 std::vector<uint16_t> expected;
64};
65
David Benjaminfb974e62015-12-16 19:34:22 -050066static const CipherTest kCipherTests[] = {
67 // Selecting individual ciphers should work.
68 {
69 "ECDHE-ECDSA-CHACHA20-POLY1305:"
70 "ECDHE-RSA-CHACHA20-POLY1305:"
71 "ECDHE-ECDSA-AES128-GCM-SHA256:"
72 "ECDHE-RSA-AES128-GCM-SHA256",
73 {
74 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
75 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
76 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
77 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
78 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
80 },
81 },
82 // + reorders selected ciphers to the end, keeping their relative order.
83 {
84 "ECDHE-ECDSA-CHACHA20-POLY1305:"
85 "ECDHE-RSA-CHACHA20-POLY1305:"
86 "ECDHE-ECDSA-AES128-GCM-SHA256:"
87 "ECDHE-RSA-AES128-GCM-SHA256:"
88 "+aRSA",
89 {
90 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
91 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
92 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
96 },
97 },
98 // ! banishes ciphers from future selections.
99 {
100 "!aRSA:"
101 "ECDHE-ECDSA-CHACHA20-POLY1305:"
102 "ECDHE-RSA-CHACHA20-POLY1305:"
103 "ECDHE-ECDSA-AES128-GCM-SHA256:"
104 "ECDHE-RSA-AES128-GCM-SHA256",
105 {
106 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
107 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
108 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // Multiple masks can be ANDed in a single rule.
112 {
113 "kRSA+AESGCM+AES128",
114 {
115 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
117 },
118 // - removes selected ciphers, but preserves their order for future
119 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
120 // ECDHE_RSA.
121 {
122 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
123 "AESGCM+AES128+aRSA",
124 {
125 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
126 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Unknown selectors are no-ops.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256:"
136 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
139 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
140 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
144 },
145 },
146 // Square brackets specify equi-preference groups.
147 {
148 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
149 "[ECDHE-RSA-CHACHA20-POLY1305]:"
150 "ECDHE-RSA-AES128-GCM-SHA256",
151 {
152 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
153 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
157 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
158 },
159 },
160 // @STRENGTH performs a stable strength-sort of the selected ciphers and
161 // only the selected ciphers.
162 {
163 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700164 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500165 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
166 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500168 // Select ECDHE ones and sort them by strength. Ties should resolve
169 // based on the order above.
170 "kECDHE:@STRENGTH:-ALL:"
171 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
172 // by strength. Then RSA, backwards by strength.
173 "aRSA",
174 {
175 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
176 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
177 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500179 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
180 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
181 },
182 },
183 // Exact ciphers may not be used in multi-part rules; they are treated
184 // as unknown aliases.
185 {
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
189 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
194 },
195 // SSLv3 matches everything that existed before TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
200 },
201 },
202 // TLSv1.2 matches everything added in TLS 1.2.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 },
208 },
209 // The two directives have no intersection.
210 {
211 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
212 {
213 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
214 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
215 },
216 },
217 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
218 // name and not an alias. It may not be used in a multipart rule. (That the
219 // shared name works is covered by the standard tests.)
220 {
221 "ECDHE-ECDSA-CHACHA20-POLY1305:"
222 "ECDHE-RSA-CHACHA20-POLY1305:"
223 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
224 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
225 {
226 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
228 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
229 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
230 },
231 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232};
233
234static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
237 "RSA]",
238 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400244 "",
245 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400246 // COMPLEMENTOFDEFAULT is empty.
247 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400248 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400249 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400250 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400251 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
252 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
253 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700255 // Opcode supplied, but missing selector.
256 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400257};
258
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700259static const char *kMustNotIncludeNull[] = {
260 "ALL",
261 "DEFAULT",
262 "ALL:!eNULL",
263 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500264 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700265 "FIPS",
266 "SHA",
267 "SHA1",
268 "RSA",
269 "SSLv3",
270 "TLSv1",
271 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700272};
273
Matt Braithwaite053931e2016-05-25 12:06:05 -0700274static const char *kMustNotIncludeCECPQ1[] = {
275 "ALL",
276 "DEFAULT",
Matt Braithwaite053931e2016-05-25 12:06:05 -0700277 "HIGH",
278 "FIPS",
279 "SHA",
280 "SHA1",
281 "SHA256",
282 "SHA384",
283 "RSA",
284 "SSLv3",
285 "TLSv1",
286 "TLSv1.2",
287 "aRSA",
288 "RSA",
289 "aECDSA",
290 "ECDSA",
291 "AES",
292 "AES128",
293 "AES256",
294 "AESGCM",
295 "CHACHA20",
296};
297
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100298static const CurveTest kCurveTests[] = {
299 {
300 "P-256",
301 { SSL_CURVE_SECP256R1 },
302 },
303 {
304 "P-256:P-384:P-521:X25519",
305 {
306 SSL_CURVE_SECP256R1,
307 SSL_CURVE_SECP384R1,
308 SSL_CURVE_SECP521R1,
309 SSL_CURVE_X25519,
310 },
311 },
312};
313
314static const char *kBadCurvesLists[] = {
315 "",
316 ":",
317 "::",
318 "P-256::X25519",
319 "RSA:P-256",
320 "P-256:RSA",
321 "X25519:P-256:",
322 ":X25519:P-256",
323};
324
David Benjamin1d77e562015-03-22 17:22:08 -0400325static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
326 bool in_group = false;
327 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400328 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
329 if (!in_group && list->in_group_flags[i]) {
330 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400331 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400332 }
333 fprintf(stderr, "\t");
334 if (in_group) {
335 fprintf(stderr, " ");
336 }
337 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
338 if (in_group && !list->in_group_flags[i]) {
339 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400340 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400341 }
342 }
343}
344
David Benjaminfb974e62015-12-16 19:34:22 -0500345static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700346 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400347 if (!ctx) {
348 return false;
David Benjamin65226252015-02-05 16:49:47 -0500349 }
350
David Benjaminfb974e62015-12-16 19:34:22 -0500351 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
352 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400353 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354 }
355
David Benjamin1d77e562015-03-22 17:22:08 -0400356 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500357 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
358 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
359 PrintCipherPreferenceList(ctx->cipher_list);
360 return false;
361 }
362
363 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 const SSL_CIPHER *cipher =
365 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500366 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
367 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
368 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400369 PrintCipherPreferenceList(ctx->cipher_list);
370 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400371 }
372 }
373
David Benjamin1d77e562015-03-22 17:22:08 -0400374 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400375}
376
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700377static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700378 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700379 if (!ctx) {
380 return false;
381 }
382 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
383 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
384 return false;
385 }
386 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
387 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
388 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
389 return false;
390 }
391 }
392 return true;
393}
394
Matt Braithwaite053931e2016-05-25 12:06:05 -0700395static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700396 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700397 if (!ctx) {
398 return false;
399 }
400 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
401 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
402 return false;
403 }
404 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
405 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
406 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
407 return false;
408 }
409 }
410 return true;
411}
412
David Benjamin1d77e562015-03-22 17:22:08 -0400413static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500414 for (const CipherTest &test : kCipherTests) {
415 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400416 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400417 }
418 }
419
David Benjaminfb974e62015-12-16 19:34:22 -0500420 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700421 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400422 if (!ctx) {
423 return false;
David Benjamin65226252015-02-05 16:49:47 -0500424 }
David Benjaminfb974e62015-12-16 19:34:22 -0500425 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
426 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400427 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400428 }
429 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400430 }
431
David Benjaminfb974e62015-12-16 19:34:22 -0500432 for (const char *rule : kMustNotIncludeNull) {
433 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700434 return false;
435 }
436 }
437
Matt Braithwaite053931e2016-05-25 12:06:05 -0700438 for (const char *rule : kMustNotIncludeCECPQ1) {
439 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
440 return false;
441 }
442 }
443
David Benjamin1d77e562015-03-22 17:22:08 -0400444 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400445}
David Benjamin2e521212014-07-16 14:37:51 -0400446
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100447static bool TestCurveRule(const CurveTest &t) {
448 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
449 if (!ctx) {
450 return false;
451 }
452
453 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
454 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
455 return false;
456 }
457
458 // Compare the two lists.
459 if (ctx->supported_group_list_len != t.expected.size()) {
460 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
461 return false;
462 }
463
464 for (size_t i = 0; i < t.expected.size(); i++) {
465 if (t.expected[i] != ctx->supported_group_list[i]) {
466 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
467 return false;
468 }
469 }
470
471 return true;
472}
473
474static bool TestCurveRules() {
475 for (const CurveTest &test : kCurveTests) {
476 if (!TestCurveRule(test)) {
477 return false;
478 }
479 }
480
481 for (const char *rule : kBadCurvesLists) {
482 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
483 if (!ctx) {
484 return false;
485 }
486 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
487 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
488 return false;
489 }
490 ERR_clear_error();
491 }
492
493 return true;
494}
495
Adam Langley10f97f32016-07-12 08:09:33 -0700496// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
497// s_client -sess_out.
498static const char kOpenSSLSession[] =
499 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
500 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
501 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
502 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
503 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
504 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
505 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
506 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
507 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
508 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
509 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
510 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
511 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
512 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
513 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
514 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
515 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
516 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
517 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
518 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
519 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
520 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
521 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
522 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
523 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
524 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
525 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
526 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
527 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
528 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
529 "i4gv7Y5oliyn";
530
531// kCustomSession is a custom serialized SSL_SESSION generated by
532// filling in missing fields from |kOpenSSLSession|. This includes
533// providing |peer_sha256|, so |peer| is not serialized.
534static const char kCustomSession[] =
535 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
536 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
537 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
538 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
539 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
540 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
541 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
542 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
543
544// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
545static const char kBoringSSLSession[] =
546 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
547 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
548 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
549 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
550 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
551 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
552 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
553 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
554 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
555 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
556 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
557 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
558 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
559 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
560 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
561 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
562 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
563 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
564 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
565 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
566 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
567 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
568 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
569 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
570 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
571 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
572 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
573 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
574 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
575 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
576 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
577 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
578 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
579 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
580 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
581 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
582 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
583 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
584 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
585 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
586 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
587 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
588 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
589 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
590 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
591 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
592 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
593 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
594 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
595 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
596 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
597 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
598 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
599 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
600 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
601 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
602 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
603 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
604 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
605 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
606 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
607 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
608 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
609 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
610 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
611 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
612 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
613 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
614 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
615 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
616 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
617 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
618 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
619 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
620 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
621 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
622 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
623 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
624 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
625 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
626 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
627 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
628 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
629 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
630 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
631 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
632 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
633 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
634 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
635 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
636 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
637 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
638 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
639 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
640 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
641
642// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
643// the final (optional) element of |kCustomSession| with tag number 30.
644static const char kBadSessionExtraField[] =
645 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
646 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
647 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
648 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
649 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
650 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
651 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
652 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
653
654// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
655// the version of |kCustomSession| with 2.
656static const char kBadSessionVersion[] =
657 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
658 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
659 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
660 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
661 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
662 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
663 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
664 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
665
666// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
667// appended.
668static const char kBadSessionTrailingData[] =
669 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
670 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
671 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
672 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
673 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
674 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
675 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
676 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
677
David Benjamin1d77e562015-03-22 17:22:08 -0400678static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400679 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400680 if (!EVP_DecodedLength(&len, strlen(in))) {
681 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400682 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400683 }
684
David Benjamin1d77e562015-03-22 17:22:08 -0400685 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800686 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400687 strlen(in))) {
688 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400689 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400690 }
David Benjamin1d77e562015-03-22 17:22:08 -0400691 out->resize(len);
692 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400693}
694
David Benjamin1d77e562015-03-22 17:22:08 -0400695static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400696 const uint8_t *cptr;
697 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400698
David Benjamin1d77e562015-03-22 17:22:08 -0400699 // Decode the input.
700 std::vector<uint8_t> input;
701 if (!DecodeBase64(&input, input_b64)) {
702 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400703 }
704
David Benjamin1d77e562015-03-22 17:22:08 -0400705 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700706 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400707 if (!session) {
708 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400709 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400710 }
711
David Benjamin1d77e562015-03-22 17:22:08 -0400712 // Verify the SSL_SESSION encoding round-trips.
713 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700714 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400715 uint8_t *encoded_raw;
716 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400717 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400718 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400719 }
David Benjamin1d77e562015-03-22 17:22:08 -0400720 encoded.reset(encoded_raw);
721 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800722 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400723 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200724 hexdump(stderr, "Before: ", input.data(), input.size());
725 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400726 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400727 }
David Benjamin3cac4502014-10-21 01:46:30 -0400728
David Benjaminfd67aa82015-06-15 19:41:48 -0400729 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800730 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800732 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400733 fprintf(stderr, "d2i_SSL_SESSION failed\n");
734 return false;
735 }
736
David Benjamin1d77e562015-03-22 17:22:08 -0400737 // Verify the SSL_SESSION encoding round-trips via the legacy API.
738 int len = i2d_SSL_SESSION(session.get(), NULL);
739 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400740 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400741 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400742 }
743
David Benjamin1d77e562015-03-22 17:22:08 -0400744 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
745 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400746 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400747 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400748 }
David Benjamin1d77e562015-03-22 17:22:08 -0400749
750 ptr = encoded.get();
751 len = i2d_SSL_SESSION(session.get(), &ptr);
752 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400753 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400754 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400755 }
David Benjamin1d77e562015-03-22 17:22:08 -0400756 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400757 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400758 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400759 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800760 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400761 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400763 }
764
David Benjamin1d77e562015-03-22 17:22:08 -0400765 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400766}
767
David Benjaminf297e022015-05-28 19:55:29 -0400768static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
769 std::vector<uint8_t> input;
770 if (!DecodeBase64(&input, input_b64)) {
771 return false;
772 }
773
774 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700775 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400776 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400777 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400778 return false;
779 }
780 ERR_clear_error();
781 return true;
782}
783
David Benjamin10e664b2016-06-20 22:20:47 -0400784static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400785 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700786 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400787 if (!ctx) {
788 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500789 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400790 if (ctx->min_version != min_version || ctx->max_version != max_version) {
791 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
792 ctx->min_version, ctx->max_version, min_version, max_version);
793 return false;
794 }
795 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500796}
797
David Benjamin1d77e562015-03-22 17:22:08 -0400798static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500799 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
800 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400801 return false;
David Benjamin65226252015-02-05 16:49:47 -0500802 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700803 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400804 if (!rfc_name) {
805 return false;
806 }
David Benjamin67be0482015-04-20 16:19:00 -0400807 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400808 return true;
David Benjamin65226252015-02-05 16:49:47 -0500809}
810
811typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500812 int id;
David Benjamin65226252015-02-05 16:49:47 -0500813 const char *rfc_name;
814} CIPHER_RFC_NAME_TEST;
815
816static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400817 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
818 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
819 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
820 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
821 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
822 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
823 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
824 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
825 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
826 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
827 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
828 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
829 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
830 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
831 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
832 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
833 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
834 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
835 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
836 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
837 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
838 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
839
840 // These names are non-standard:
841 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
842 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
843 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
844 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500845};
846
David Benjamin1d77e562015-03-22 17:22:08 -0400847static bool TestCipherGetRFCName(void) {
848 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400849 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500850 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400851 std::string rfc_name;
852 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
853 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
854 return false;
David Benjamin65226252015-02-05 16:49:47 -0500855 }
David Benjamin1d77e562015-03-22 17:22:08 -0400856 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500857 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400858 rfc_name.c_str(), test->rfc_name);
859 return false;
David Benjamin65226252015-02-05 16:49:47 -0500860 }
David Benjamin65226252015-02-05 16:49:47 -0500861 }
David Benjamin1d77e562015-03-22 17:22:08 -0400862 return true;
David Benjamin65226252015-02-05 16:49:47 -0500863}
864
David Benjamin422fe082015-07-21 22:03:43 -0400865// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
866// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700867static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400868 std::vector<uint8_t> der;
869 if (!DecodeBase64(&der, kOpenSSLSession)) {
870 return nullptr;
871 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700872 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400873 if (!session) {
874 return nullptr;
875 }
876
877 // Swap out the ticket for a garbage one.
878 OPENSSL_free(session->tlsext_tick);
879 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
880 if (session->tlsext_tick == nullptr) {
881 return nullptr;
882 }
883 memset(session->tlsext_tick, 'a', ticket_len);
884 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400885
886 // Fix up the timeout.
887 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400888 return session;
889}
890
David Benjaminafc64de2016-07-19 17:12:41 +0200891static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700892 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200893 if (!bio) {
894 return false;
895 }
896 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400897 BIO_up_ref(bio.get());
898 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200899 int ret = SSL_connect(ssl);
900 if (ret > 0) {
901 // SSL_connect should fail without a BIO to write to.
902 return false;
903 }
904 ERR_clear_error();
905
906 const uint8_t *client_hello;
907 size_t client_hello_len;
908 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
909 return false;
910 }
911 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
912 return true;
913}
914
David Benjamin422fe082015-07-21 22:03:43 -0400915// GetClientHelloLen creates a client SSL connection with a ticket of length
916// |ticket_len| and records the ClientHello. It returns the length of the
917// ClientHello, not including the record header, on success and zero on error.
918static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700919 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
920 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400921 if (!ctx || !session) {
922 return 0;
923 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700924 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400925 // Test at TLS 1.2. TLS 1.3 adds enough extensions that the ClientHello is
926 // longer than our test vectors.
927 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
928 !SSL_set_max_proto_version(ssl.get(), TLS1_2_VERSION)) {
David Benjamin422fe082015-07-21 22:03:43 -0400929 return 0;
930 }
David Benjaminafc64de2016-07-19 17:12:41 +0200931 std::vector<uint8_t> client_hello;
932 if (!GetClientHello(ssl.get(), &client_hello) ||
933 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400934 return 0;
935 }
David Benjaminafc64de2016-07-19 17:12:41 +0200936 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400937}
938
939struct PaddingTest {
940 size_t input_len, padded_len;
941};
942
943static const PaddingTest kPaddingTests[] = {
944 // ClientHellos of length below 0x100 do not require padding.
945 {0xfe, 0xfe},
946 {0xff, 0xff},
947 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
948 {0x100, 0x200},
949 {0x123, 0x200},
950 {0x1fb, 0x200},
951 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
952 // padding extension takes a minimum of four bytes plus one required content
953 // byte. (To work around yet more server bugs, we avoid empty final
954 // extensions.)
955 {0x1fc, 0x201},
956 {0x1fd, 0x202},
957 {0x1fe, 0x203},
958 {0x1ff, 0x204},
959 // Finally, larger ClientHellos need no padding.
960 {0x200, 0x200},
961 {0x201, 0x201},
962};
963
964static bool TestPaddingExtension() {
965 // Sample a baseline length.
966 size_t base_len = GetClientHelloLen(1);
967 if (base_len == 0) {
968 return false;
969 }
970
971 for (const PaddingTest &test : kPaddingTests) {
972 if (base_len > test.input_len) {
973 fprintf(stderr, "Baseline ClientHello too long.\n");
974 return false;
975 }
976
977 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
978 if (padded_len != test.padded_len) {
979 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
980 static_cast<unsigned>(test.input_len),
981 static_cast<unsigned>(padded_len),
982 static_cast<unsigned>(test.padded_len));
983 return false;
984 }
985 }
986 return true;
987}
988
David Benjamin1d128f32015-09-08 17:41:40 -0400989// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
990// before configuring as a server.
991static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700992 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400993 if (!ctx) {
994 return false;
995 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700996 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400997 if (!ssl) {
998 return false;
999 }
1000
1001 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
1002 if (stack == nullptr) {
1003 return false;
1004 }
1005 // |SSL_set_client_CA_list| takes ownership.
1006 SSL_set_client_CA_list(ssl.get(), stack);
1007
1008 return SSL_get_client_CA_list(ssl.get()) == stack;
1009}
1010
David Benjamin0f653952015-10-18 14:28:01 -04001011static void AppendSession(SSL_SESSION *session, void *arg) {
1012 std::vector<SSL_SESSION*> *out =
1013 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1014 out->push_back(session);
1015}
1016
1017// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1018// order.
1019static bool ExpectCache(SSL_CTX *ctx,
1020 const std::vector<SSL_SESSION*> &expected) {
1021 // Check the linked list.
1022 SSL_SESSION *ptr = ctx->session_cache_head;
1023 for (SSL_SESSION *session : expected) {
1024 if (ptr != session) {
1025 return false;
1026 }
1027 // TODO(davidben): This is an absurd way to denote the end of the list.
1028 if (ptr->next ==
1029 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1030 ptr = nullptr;
1031 } else {
1032 ptr = ptr->next;
1033 }
1034 }
1035 if (ptr != nullptr) {
1036 return false;
1037 }
1038
1039 // Check the hash table.
1040 std::vector<SSL_SESSION*> actual, expected_copy;
1041 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1042 expected_copy = expected;
1043
1044 std::sort(actual.begin(), actual.end());
1045 std::sort(expected_copy.begin(), expected_copy.end());
1046
1047 return actual == expected_copy;
1048}
1049
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001050static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1051 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001052 if (!ret) {
1053 return nullptr;
1054 }
1055
1056 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1057 memset(ret->session_id, 0, ret->session_id_length);
1058 memcpy(ret->session_id, &number, sizeof(number));
1059 return ret;
1060}
1061
David Benjamin0f653952015-10-18 14:28:01 -04001062// Test that the internal session cache behaves as expected.
1063static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001064 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001065 if (!ctx) {
1066 return false;
1067 }
1068
1069 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001070 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001071 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001072 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001073 if (!session) {
1074 return false;
1075 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001076 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001077 }
1078
1079 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1080
1081 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001082 for (const auto &session : sessions) {
1083 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001084 return false;
1085 }
1086 }
1087
1088 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001089 std::vector<SSL_SESSION*> expected = {
1090 sessions[9].get(),
1091 sessions[8].get(),
1092 sessions[7].get(),
1093 sessions[6].get(),
1094 sessions[5].get(),
1095 };
David Benjamin0f653952015-10-18 14:28:01 -04001096 if (!ExpectCache(ctx.get(), expected)) {
1097 return false;
1098 }
1099
1100 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001101 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001102 !ExpectCache(ctx.get(), expected)) {
1103 return false;
1104 }
1105
1106 // Although collisions should be impossible (256-bit session IDs), the cache
1107 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001108 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001109 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1110 return false;
1111 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001112 expected = {
1113 collision.get(),
1114 sessions[9].get(),
1115 sessions[8].get(),
1116 sessions[6].get(),
1117 sessions[5].get(),
1118 };
David Benjamin0f653952015-10-18 14:28:01 -04001119 if (!ExpectCache(ctx.get(), expected)) {
1120 return false;
1121 }
1122
1123 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001124 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001125 return false;
1126 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001127 expected = {
1128 collision.get(),
1129 sessions[9].get(),
1130 sessions[8].get(),
1131 sessions[5].get(),
1132 };
David Benjamin0f653952015-10-18 14:28:01 -04001133 if (!ExpectCache(ctx.get(), expected)) {
1134 return false;
1135 }
1136
1137 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001138 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1139 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001140 !ExpectCache(ctx.get(), expected)) {
1141 return false;
1142 }
1143
1144 return true;
1145}
1146
David Benjaminde942382016-02-11 12:02:01 -05001147static uint16_t EpochFromSequence(uint64_t seq) {
1148 return static_cast<uint16_t>(seq >> 48);
1149}
1150
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001151static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001152 static const char kCertPEM[] =
1153 "-----BEGIN CERTIFICATE-----\n"
1154 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1155 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1156 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1157 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1158 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1159 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1160 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1161 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1162 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1163 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1164 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1165 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1166 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1167 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001168 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1169 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001170}
1171
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001172static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001173 static const char kKeyPEM[] =
1174 "-----BEGIN RSA PRIVATE KEY-----\n"
1175 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1176 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1177 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1178 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1179 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1180 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1181 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1182 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1183 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1184 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1185 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1186 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1187 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1188 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001189 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1190 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001191 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1192}
1193
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001194static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001195 static const char kCertPEM[] =
1196 "-----BEGIN CERTIFICATE-----\n"
1197 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1198 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1199 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1200 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1201 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1202 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1203 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1204 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1205 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1206 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1207 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001208 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1209 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001210}
1211
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001212static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001213 static const char kKeyPEM[] =
1214 "-----BEGIN PRIVATE KEY-----\n"
1215 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1216 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1217 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1218 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001219 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1220 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001221 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1222}
1223
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001224static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001225 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1226 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001227 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001228 if (!client || !server) {
1229 return false;
1230 }
1231 SSL_set_connect_state(client.get());
1232 SSL_set_accept_state(server.get());
1233
David Benjamina20e5352016-08-02 19:09:41 -04001234 SSL_set_session(client.get(), session);
1235
David Benjaminde942382016-02-11 12:02:01 -05001236 BIO *bio1, *bio2;
1237 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1238 return false;
1239 }
1240 // SSL_set_bio takes ownership.
1241 SSL_set_bio(client.get(), bio1, bio1);
1242 SSL_set_bio(server.get(), bio2, bio2);
1243
1244 // Drive both their handshakes to completion.
1245 for (;;) {
1246 int client_ret = SSL_do_handshake(client.get());
1247 int client_err = SSL_get_error(client.get(), client_ret);
1248 if (client_err != SSL_ERROR_NONE &&
1249 client_err != SSL_ERROR_WANT_READ &&
1250 client_err != SSL_ERROR_WANT_WRITE) {
1251 fprintf(stderr, "Client error: %d\n", client_err);
1252 return false;
1253 }
1254
1255 int server_ret = SSL_do_handshake(server.get());
1256 int server_err = SSL_get_error(server.get(), server_ret);
1257 if (server_err != SSL_ERROR_NONE &&
1258 server_err != SSL_ERROR_WANT_READ &&
1259 server_err != SSL_ERROR_WANT_WRITE) {
1260 fprintf(stderr, "Server error: %d\n", server_err);
1261 return false;
1262 }
1263
1264 if (client_ret == 1 && server_ret == 1) {
1265 break;
1266 }
1267 }
1268
David Benjamin686bb192016-05-10 15:15:41 -04001269 *out_client = std::move(client);
1270 *out_server = std::move(server);
1271 return true;
1272}
1273
Steven Valdez2c62fe92016-10-14 12:08:12 -04001274static uint16_t kTLSVersions[] = {
1275 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1276};
David Benjamin686bb192016-05-10 15:15:41 -04001277
Steven Valdez2c62fe92016-10-14 12:08:12 -04001278static uint16_t kDTLSVersions[] = {
1279 DTLS1_VERSION, DTLS1_2_VERSION,
1280};
David Benjamin686bb192016-05-10 15:15:41 -04001281
Steven Valdez2c62fe92016-10-14 12:08:12 -04001282static bool TestSequenceNumber() {
1283 for (bool is_dtls : std::vector<bool>{false, true}) {
1284 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
1285 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
1286 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
1287 : OPENSSL_ARRAY_SIZE(kTLSVersions);
1288 for (size_t i = 0; i < num_versions; i++) {
1289 uint16_t version = versions[i];
1290 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1291 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1292 if (!server_ctx || !client_ctx ||
1293 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1294 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1295 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1296 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1297 return false;
1298 }
David Benjamin686bb192016-05-10 15:15:41 -04001299
Steven Valdez2c62fe92016-10-14 12:08:12 -04001300 bssl::UniquePtr<X509> cert = GetTestCertificate();
1301 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1302 if (!cert || !key ||
1303 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1304 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1305 return false;
1306 }
David Benjaminde942382016-02-11 12:02:01 -05001307
Steven Valdez2c62fe92016-10-14 12:08:12 -04001308 bssl::UniquePtr<SSL> client, server;
1309 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1310 server_ctx.get(), nullptr /* no session */)) {
1311 return false;
1312 }
1313
1314 // Drain any post-handshake messages to ensure there are no unread records
1315 // on either end.
1316 uint8_t byte = 0;
1317 if (SSL_read(client.get(), &byte, 1) > 0 ||
1318 SSL_read(server.get(), &byte, 1) > 0) {
1319 fprintf(stderr, "Received unexpected data.\n");
1320 return false;
1321 }
1322
1323 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1324 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1325 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1326 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1327
1328 if (is_dtls) {
1329 // Both client and server must be at epoch 1.
1330 if (EpochFromSequence(client_read_seq) != 1 ||
1331 EpochFromSequence(client_write_seq) != 1 ||
1332 EpochFromSequence(server_read_seq) != 1 ||
1333 EpochFromSequence(server_write_seq) != 1) {
1334 fprintf(stderr, "Bad epochs.\n");
1335 return false;
1336 }
1337
1338 // The next record to be written should exceed the largest received.
1339 if (client_write_seq <= server_read_seq ||
1340 server_write_seq <= client_read_seq) {
1341 fprintf(stderr, "Inconsistent sequence numbers.\n");
1342 return false;
1343 }
1344 } else {
1345 // The next record to be written should equal the next to be received.
1346 if (client_write_seq != server_read_seq ||
1347 server_write_seq != client_read_seq) {
1348 fprintf(stderr, "Inconsistent sequence numbers.\n");
1349 return false;
1350 }
1351 }
1352
1353 // Send a record from client to server.
1354 if (SSL_write(client.get(), &byte, 1) != 1 ||
1355 SSL_read(server.get(), &byte, 1) != 1) {
1356 fprintf(stderr, "Could not send byte.\n");
1357 return false;
1358 }
1359
1360 // The client write and server read sequence numbers should have
1361 // incremented.
1362 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1363 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1364 fprintf(stderr, "Sequence numbers did not increment.\n");
1365 return false;
1366 }
David Benjaminde942382016-02-11 12:02:01 -05001367 }
David Benjaminde942382016-02-11 12:02:01 -05001368 }
1369
1370 return true;
1371}
1372
David Benjamin686bb192016-05-10 15:15:41 -04001373static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001374 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1375 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001376 if (!client_ctx || !server_ctx) {
1377 return false;
1378 }
1379
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001380 bssl::UniquePtr<X509> cert = GetTestCertificate();
1381 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001382 if (!cert || !key ||
1383 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1384 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1385 return false;
1386 }
1387
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001388 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001389 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001390 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001391 return false;
1392 }
1393
1394 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1395 // one side has shut down.
1396 if (SSL_shutdown(client.get()) != 0) {
1397 fprintf(stderr, "Could not shutdown.\n");
1398 return false;
1399 }
1400
1401 // Reading from the server should consume the EOF.
1402 uint8_t byte;
1403 if (SSL_read(server.get(), &byte, 1) != 0 ||
1404 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1405 fprintf(stderr, "Connection was not shut down cleanly.\n");
1406 return false;
1407 }
1408
1409 // However, the server may continue to write data and then shut down the
1410 // connection.
1411 byte = 42;
1412 if (SSL_write(server.get(), &byte, 1) != 1 ||
1413 SSL_read(client.get(), &byte, 1) != 1 ||
1414 byte != 42) {
1415 fprintf(stderr, "Could not send byte.\n");
1416 return false;
1417 }
1418
1419 // The server may then shutdown the connection.
1420 if (SSL_shutdown(server.get()) != 1 ||
1421 SSL_shutdown(client.get()) != 1) {
1422 fprintf(stderr, "Could not complete shutdown.\n");
1423 return false;
1424 }
1425
1426 return true;
1427}
Steven Valdez87eab492016-06-27 16:34:59 -04001428static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001429 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1430 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001431 if (!client_ctx || !server_ctx) {
1432 return false;
1433 }
1434
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001435 bssl::UniquePtr<X509> cert = GetTestCertificate();
1436 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001437 if (!cert || !key ||
1438 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1439 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1440 return false;
1441 }
1442
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001443 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001444 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001445 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001446 return false;
1447 }
1448
1449 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001450 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001451 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001452 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001453 }
David Benjamin4501bd52016-08-01 13:39:41 -04001454
Steven Valdez84b5c002016-08-25 16:30:58 -04001455 session1->not_resumable = 0;
1456
Steven Valdez87eab492016-06-27 16:34:59 -04001457 uint8_t *s0_bytes, *s1_bytes;
1458 size_t s0_len, s1_len;
1459
1460 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1461 return false;
1462 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001463 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001464
1465 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1466 return false;
1467 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001468 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001469
1470 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1471}
David Benjamin686bb192016-05-10 15:15:41 -04001472
David Benjamin5c0fb882016-06-14 14:03:51 -04001473static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1474 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1475 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1476 SSL_get_wfd(ssl), rfd, wfd);
1477 return false;
1478 }
1479
1480 // The wrapper BIOs are always equal when fds are equal, even if set
1481 // individually.
1482 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1483 fprintf(stderr, "rbio and wbio did not match.\n");
1484 return false;
1485 }
1486
1487 return true;
1488}
1489
1490static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001491 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001492 if (!ctx) {
1493 return false;
1494 }
1495
1496 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001497 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001498 if (!ssl ||
1499 !SSL_set_rfd(ssl.get(), 1) ||
1500 !SSL_set_wfd(ssl.get(), 2) ||
1501 !ExpectFDs(ssl.get(), 1, 2)) {
1502 return false;
1503 }
1504
1505 // Test setting the same FD.
1506 ssl.reset(SSL_new(ctx.get()));
1507 if (!ssl ||
1508 !SSL_set_fd(ssl.get(), 1) ||
1509 !ExpectFDs(ssl.get(), 1, 1)) {
1510 return false;
1511 }
1512
1513 // Test setting the same FD one side at a time.
1514 ssl.reset(SSL_new(ctx.get()));
1515 if (!ssl ||
1516 !SSL_set_rfd(ssl.get(), 1) ||
1517 !SSL_set_wfd(ssl.get(), 1) ||
1518 !ExpectFDs(ssl.get(), 1, 1)) {
1519 return false;
1520 }
1521
1522 // Test setting the same FD in the other order.
1523 ssl.reset(SSL_new(ctx.get()));
1524 if (!ssl ||
1525 !SSL_set_wfd(ssl.get(), 1) ||
1526 !SSL_set_rfd(ssl.get(), 1) ||
1527 !ExpectFDs(ssl.get(), 1, 1)) {
1528 return false;
1529 }
1530
David Benjamin5c0fb882016-06-14 14:03:51 -04001531 // Test changing the read FD partway through.
1532 ssl.reset(SSL_new(ctx.get()));
1533 if (!ssl ||
1534 !SSL_set_fd(ssl.get(), 1) ||
1535 !SSL_set_rfd(ssl.get(), 2) ||
1536 !ExpectFDs(ssl.get(), 2, 1)) {
1537 return false;
1538 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001539
1540 // Test changing the write FD partway through.
1541 ssl.reset(SSL_new(ctx.get()));
1542 if (!ssl ||
1543 !SSL_set_fd(ssl.get(), 1) ||
1544 !SSL_set_wfd(ssl.get(), 2) ||
1545 !ExpectFDs(ssl.get(), 1, 2)) {
1546 return false;
1547 }
1548
1549 // Test a no-op change to the read FD partway through.
1550 ssl.reset(SSL_new(ctx.get()));
1551 if (!ssl ||
1552 !SSL_set_fd(ssl.get(), 1) ||
1553 !SSL_set_rfd(ssl.get(), 1) ||
1554 !ExpectFDs(ssl.get(), 1, 1)) {
1555 return false;
1556 }
1557
1558 // Test a no-op change to the write FD partway through.
1559 ssl.reset(SSL_new(ctx.get()));
1560 if (!ssl ||
1561 !SSL_set_fd(ssl.get(), 1) ||
1562 !SSL_set_wfd(ssl.get(), 1) ||
1563 !ExpectFDs(ssl.get(), 1, 1)) {
1564 return false;
1565 }
1566
1567 // ASan builds will implicitly test that the internal |BIO| reference-counting
1568 // is correct.
1569
1570 return true;
1571}
1572
David Benjamin4501bd52016-08-01 13:39:41 -04001573static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001574 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001575 if (!ctx) {
1576 return false;
1577 }
1578
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001579 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1580 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001581 bio3(BIO_new(BIO_s_mem()));
1582 if (!ssl || !bio1 || !bio2 || !bio3) {
1583 return false;
1584 }
1585
1586 // SSL_set_bio takes one reference when the parameters are the same.
1587 BIO_up_ref(bio1.get());
1588 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1589
1590 // Repeating the call does nothing.
1591 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1592
1593 // It takes one reference each when the parameters are different.
1594 BIO_up_ref(bio2.get());
1595 BIO_up_ref(bio3.get());
1596 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1597
1598 // Repeating the call does nothing.
1599 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1600
1601 // It takes one reference when changing only wbio.
1602 BIO_up_ref(bio1.get());
1603 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1604
1605 // It takes one reference when changing only rbio and the two are different.
1606 BIO_up_ref(bio3.get());
1607 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1608
1609 // If setting wbio to rbio, it takes no additional references.
1610 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1611
1612 // From there, wbio may be switched to something else.
1613 BIO_up_ref(bio1.get());
1614 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1615
1616 // If setting rbio to wbio, it takes no additional references.
1617 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1618
1619 // From there, rbio may be switched to something else, but, for historical
1620 // reasons, it takes a reference to both parameters.
1621 BIO_up_ref(bio1.get());
1622 BIO_up_ref(bio2.get());
1623 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1624
1625 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1626 // is correct.
1627 return true;
1628}
1629
David Benjamin25490f22016-07-14 00:22:54 -04001630static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1631
David Benjaminadd5e522016-07-14 00:33:24 -04001632static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001633 bssl::UniquePtr<X509> cert = GetTestCertificate();
1634 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001635 if (!cert || !key) {
1636 return false;
1637 }
1638
David Benjamincb18ac22016-09-27 14:09:15 -04001639 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001640 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001641 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001642 if (!ctx ||
1643 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001644 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001645 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1646 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001647 return false;
1648 }
David Benjaminadd5e522016-07-14 00:33:24 -04001649 SSL_CTX_set_verify(
1650 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1651 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1652
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001653 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001654 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1655 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001656 return false;
1657 }
1658
1659 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001660 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001661 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1662 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1663 return false;
1664 }
1665
1666 peer.reset(SSL_get_peer_certificate(client.get()));
1667 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1668 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1669 return false;
1670 }
1671
1672 // However, for historical reasons, the chain includes the leaf on the
1673 // client, but does not on the server.
1674 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1675 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1676 return false;
1677 }
1678
1679 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1680 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1681 return false;
1682 }
1683 }
1684
1685 return true;
1686}
1687
David Benjamin25490f22016-07-14 00:22:54 -04001688static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001689 bssl::UniquePtr<X509> cert = GetTestCertificate();
1690 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001691 if (!cert || !key) {
1692 return false;
1693 }
1694
1695 uint8_t *cert_der = NULL;
1696 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1697 if (cert_der_len < 0) {
1698 return false;
1699 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001700 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001701
1702 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1703 SHA256(cert_der, cert_der_len, cert_sha256);
1704
David Benjamincb18ac22016-09-27 14:09:15 -04001705 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001706 // Configure both client and server to accept any certificate, but the
1707 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001708 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001709 if (!ctx ||
1710 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001711 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001712 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1713 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001714 return false;
1715 }
David Benjamin25490f22016-07-14 00:22:54 -04001716 SSL_CTX_set_verify(
1717 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1718 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1719 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1720
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001721 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001722 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1723 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001724 return false;
1725 }
1726
1727 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001728 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001729 if (peer) {
1730 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1731 return false;
1732 }
1733
1734 SSL_SESSION *session = SSL_get_session(server.get());
1735 if (!session->peer_sha256_valid) {
1736 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1737 return false;
1738 }
1739
1740 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1741 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1742 return false;
1743 }
1744 }
1745
1746 return true;
1747}
1748
David Benjaminafc64de2016-07-19 17:12:41 +02001749static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1750 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001751 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001752 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001753 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001754 // Our default cipher list varies by CPU capabilities, so manually place
1755 // the ChaCha20 ciphers in front.
1756 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001757 return false;
1758 }
David Benjamin2dc02042016-09-19 19:57:37 -04001759
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001760 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001761 if (!ssl) {
1762 return false;
1763 }
1764 std::vector<uint8_t> client_hello;
1765 if (!GetClientHello(ssl.get(), &client_hello)) {
1766 return false;
1767 }
1768
1769 // Zero the client_random.
1770 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1771 1 + 3 + // handshake message header
1772 2; // client_version
1773 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1774 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1775 return false;
1776 }
1777 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1778
1779 if (client_hello.size() != expected_len ||
1780 memcmp(client_hello.data(), expected, expected_len) != 0) {
1781 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1782 fprintf(stderr, "Got:\n\t");
1783 for (size_t i = 0; i < client_hello.size(); i++) {
1784 fprintf(stderr, "0x%02x, ", client_hello[i]);
1785 }
1786 fprintf(stderr, "\nWanted:\n\t");
1787 for (size_t i = 0; i < expected_len; i++) {
1788 fprintf(stderr, "0x%02x, ", expected[i]);
1789 }
1790 fprintf(stderr, "\n");
1791 return false;
1792 }
1793
1794 return true;
1795}
1796
1797// Tests that our ClientHellos do not change unexpectedly.
1798static bool TestClientHello() {
1799 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001800 0x16,
1801 0x03, 0x00,
1802 0x00, 0x3f,
1803 0x01,
1804 0x00, 0x00, 0x3b,
1805 0x03, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00,
1811 0x00, 0x14,
1812 0xc0, 0x09,
1813 0xc0, 0x13,
1814 0x00, 0x33,
1815 0xc0, 0x0a,
1816 0xc0, 0x14,
1817 0x00, 0x39,
1818 0x00, 0x2f,
1819 0x00, 0x35,
1820 0x00, 0x0a,
1821 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001822 };
1823 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1824 sizeof(kSSL3ClientHello))) {
1825 return false;
1826 }
1827
1828 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001829 0x16,
1830 0x03, 0x01,
1831 0x00, 0x5e,
1832 0x01,
1833 0x00, 0x00, 0x5a,
1834 0x03, 0x01,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00,
1840 0x00, 0x12,
1841 0xc0, 0x09,
1842 0xc0, 0x13,
1843 0x00, 0x33,
1844 0xc0, 0x0a,
1845 0xc0, 0x14,
1846 0x00, 0x39,
1847 0x00, 0x2f,
1848 0x00, 0x35,
1849 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001850 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1851 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1852 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1853 };
1854 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1855 sizeof(kTLS1ClientHello))) {
1856 return false;
1857 }
1858
1859 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001860 0x16,
1861 0x03, 0x01,
1862 0x00, 0x5e,
1863 0x01,
1864 0x00, 0x00, 0x5a,
1865 0x03, 0x02,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00,
1871 0x00, 0x12,
1872 0xc0, 0x09,
1873 0xc0, 0x13,
1874 0x00, 0x33,
1875 0xc0, 0x0a,
1876 0xc0, 0x14,
1877 0x00, 0x39,
1878 0x00, 0x2f,
1879 0x00, 0x35,
1880 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001881 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1882 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1883 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1884 };
1885 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1886 sizeof(kTLS11ClientHello))) {
1887 return false;
1888 }
1889
1890 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001891 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1895 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1896 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1897 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1898 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001899 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001900 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001901 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1902 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001903 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1904 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001905 };
1906 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1907 sizeof(kTLS12ClientHello))) {
1908 return false;
1909 }
1910
1911 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1912 // implementation has settled enough that it won't change.
1913
1914 return true;
1915}
1916
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001917static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001918
1919static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1920 // Save the most recent session.
1921 g_last_session.reset(session);
1922 return 1;
1923}
1924
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001925static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001926 SSL_CTX *server_ctx) {
1927 g_last_session = nullptr;
1928 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1929
1930 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001931 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001932 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1933 nullptr /* no session */)) {
1934 fprintf(stderr, "Failed to connect client and server.\n");
1935 return nullptr;
1936 }
1937
1938 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1939 SSL_read(client.get(), nullptr, 0);
1940
1941 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1942
1943 if (!g_last_session) {
1944 fprintf(stderr, "Client did not receive a session.\n");
1945 return nullptr;
1946 }
1947 return std::move(g_last_session);
1948}
1949
1950static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1951 SSL_SESSION *session,
1952 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001953 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001954 if (!ConnectClientAndServer(&client, &server, client_ctx,
1955 server_ctx, session)) {
1956 fprintf(stderr, "Failed to connect client and server.\n");
1957 return false;
1958 }
1959
1960 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1961 fprintf(stderr, "Client and server were inconsistent.\n");
1962 return false;
1963 }
1964
1965 bool was_reused = !!SSL_session_reused(client.get());
1966 if (was_reused != reused) {
1967 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1968 was_reused ? "" : " not");
1969 return false;
1970 }
1971
1972 return true;
1973}
1974
1975static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001976 bssl::UniquePtr<X509> cert = GetTestCertificate();
1977 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001978 if (!cert || !key) {
1979 return false;
1980 }
1981
1982 static const uint8_t kContext1[] = {1};
1983 static const uint8_t kContext2[] = {2};
1984
David Benjamincb18ac22016-09-27 14:09:15 -04001985 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001986 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1987 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001988 if (!server_ctx || !client_ctx ||
1989 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1990 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1991 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001992 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001993 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1994 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1995 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1996 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001997 return false;
1998 }
1999
David Benjamina20e5352016-08-02 19:09:41 -04002000 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002001 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2002
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002003 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04002004 CreateClientSession(client_ctx.get(), server_ctx.get());
2005 if (!session) {
2006 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2007 return false;
2008 }
2009
2010 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2011 true /* expect session reused */)) {
2012 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2013 return false;
2014 }
2015
2016 // Change the session ID context.
2017 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2018 sizeof(kContext2))) {
2019 return false;
2020 }
2021
2022 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2023 false /* expect session not reused */)) {
2024 fprintf(stderr,
2025 "Error connection with different context (version = %04x).\n",
2026 version);
2027 return false;
2028 }
2029 }
2030
2031 return true;
2032}
2033
David Benjamin721e8b72016-08-03 13:13:17 -04002034static timeval g_current_time;
2035
2036static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2037 *out_clock = g_current_time;
2038}
2039
2040static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002041 bssl::UniquePtr<X509> cert = GetTestCertificate();
2042 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002043 if (!cert || !key) {
2044 return false;
2045 }
2046
David Benjamincb18ac22016-09-27 14:09:15 -04002047 for (uint16_t version : kTLSVersions) {
David Benjaminb2e2e322016-11-01 17:32:54 -04002048 for (bool server_test : std::vector<bool>{false, true}) {
2049 static const int kStartTime = 1000;
2050 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002051
David Benjaminb2e2e322016-11-01 17:32:54 -04002052 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2053 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2054 if (!server_ctx || !client_ctx ||
2055 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2056 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2057 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2058 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2059 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2060 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2061 return false;
2062 }
David Benjamin721e8b72016-08-03 13:13:17 -04002063
David Benjaminb2e2e322016-11-01 17:32:54 -04002064 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2065 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamin721e8b72016-08-03 13:13:17 -04002066
David Benjaminb2e2e322016-11-01 17:32:54 -04002067 // Both client and server must enforce session timeouts.
2068 if (server_test) {
2069 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2070 } else {
2071 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2072 }
David Benjamin721e8b72016-08-03 13:13:17 -04002073
David Benjaminb2e2e322016-11-01 17:32:54 -04002074 bssl::UniquePtr<SSL_SESSION> session =
2075 CreateClientSession(client_ctx.get(), server_ctx.get());
2076 if (!session) {
2077 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2078 return false;
2079 }
David Benjamin721e8b72016-08-03 13:13:17 -04002080
David Benjaminb2e2e322016-11-01 17:32:54 -04002081 // Advance the clock just behind the timeout.
2082 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
David Benjamin721e8b72016-08-03 13:13:17 -04002083
David Benjaminb2e2e322016-11-01 17:32:54 -04002084 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2085 session.get(),
2086 true /* expect session reused */)) {
2087 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2088 return false;
2089 }
David Benjamin721e8b72016-08-03 13:13:17 -04002090
David Benjaminb2e2e322016-11-01 17:32:54 -04002091 // Advance the clock one more second.
2092 g_current_time.tv_sec++;
David Benjamin721e8b72016-08-03 13:13:17 -04002093
David Benjaminb2e2e322016-11-01 17:32:54 -04002094 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2095 session.get(),
2096 false /* expect session not reused */)) {
2097 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2098 return false;
2099 }
David Benjamin1b22f852016-10-27 16:36:32 -04002100
David Benjaminb2e2e322016-11-01 17:32:54 -04002101 // Rewind the clock to before the session was minted.
2102 g_current_time.tv_sec = kStartTime - 1;
David Benjamin1b22f852016-10-27 16:36:32 -04002103
David Benjaminb2e2e322016-11-01 17:32:54 -04002104 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2105 session.get(),
2106 false /* expect session not reused */)) {
2107 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2108 return false;
2109 }
David Benjamin1b22f852016-10-27 16:36:32 -04002110 }
David Benjamin721e8b72016-08-03 13:13:17 -04002111 }
2112
2113 return true;
2114}
2115
David Benjamin0fc37ef2016-08-17 15:29:46 -04002116static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2117 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2118 SSL_set_SSL_CTX(ssl, ctx);
2119 return SSL_TLSEXT_ERR_OK;
2120}
2121
2122static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002123 bssl::UniquePtr<X509> cert = GetTestCertificate();
2124 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2125 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2126 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002127 if (!cert || !key || !cert2 || !key2) {
2128 return false;
2129 }
2130
2131 // At each version, test that switching the |SSL_CTX| at the SNI callback
2132 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002133 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002134 if (version == SSL3_VERSION) {
2135 continue;
2136 }
2137
2138 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2139
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002140 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2141 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2142 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002143 if (!server_ctx || !server_ctx2 || !client_ctx ||
2144 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2145 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2146 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2147 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2148 // Historically signing preferences would be lost in some cases with the
2149 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2150 // this doesn't happen when |version| is TLS 1.2, configure the private
2151 // key to only sign SHA-256.
2152 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002153 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002154 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2155 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2156 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2157 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2158 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2159 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002160 return false;
2161 }
2162
David Benjamin0fc37ef2016-08-17 15:29:46 -04002163 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2164 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2165
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002166 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002167 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2168 server_ctx.get(), nullptr)) {
2169 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2170 return false;
2171 }
2172
2173 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002174 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002175 if (!peer ||
2176 X509_cmp(peer.get(), cert2.get()) != 0) {
2177 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2178 version);
2179 return false;
2180 }
2181 }
2182
2183 return true;
2184}
2185
David Benjamin99620572016-08-30 00:35:36 -04002186static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002187 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002188 return -1;
2189 }
2190
David Benjamin99620572016-08-30 00:35:36 -04002191 return 1;
2192}
2193
2194// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2195// maximum version.
2196static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002197 bssl::UniquePtr<X509> cert = GetTestCertificate();
2198 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2199 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2200 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002201 if (!cert || !key || !server_ctx || !client_ctx ||
2202 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002203 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002204 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2205 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002206 return false;
2207 }
2208
David Benjamin99620572016-08-30 00:35:36 -04002209 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2210
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002211 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002212 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2213 server_ctx.get(), nullptr)) {
2214 return false;
2215 }
2216
2217 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2218 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2219 return false;
2220 }
2221
2222 return true;
2223}
2224
David Benjamin2dc02042016-09-19 19:57:37 -04002225static bool TestSetVersion() {
2226 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2227 if (!ctx) {
2228 return false;
2229 }
2230
David Benjamine4706902016-09-20 15:12:23 -04002231 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2232 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2233 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2234 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002235 fprintf(stderr, "Could not set valid TLS version.\n");
2236 return false;
2237 }
2238
David Benjamine4706902016-09-20 15:12:23 -04002239 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2240 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2241 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2242 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2243 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2244 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002245 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2246 return false;
2247 }
2248
David Benjamine34bcc92016-09-21 16:53:09 -04002249 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2250 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2251 fprintf(stderr, "Could not set default TLS version.\n");
2252 return false;
2253 }
2254
2255 if (ctx->min_version != SSL3_VERSION ||
2256 ctx->max_version != TLS1_2_VERSION) {
2257 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2258 ctx->min_version, ctx->max_version);
2259 return false;
2260 }
2261
David Benjamin2dc02042016-09-19 19:57:37 -04002262 ctx.reset(SSL_CTX_new(DTLS_method()));
2263 if (!ctx) {
2264 return false;
2265 }
2266
David Benjamine4706902016-09-20 15:12:23 -04002267 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2268 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2269 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2270 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002271 fprintf(stderr, "Could not set valid DTLS version.\n");
2272 return false;
2273 }
2274
David Benjamine4706902016-09-20 15:12:23 -04002275 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2276 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2277 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2278 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2279 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2280 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2281 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2282 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002283 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2284 return false;
2285 }
2286
David Benjamine34bcc92016-09-21 16:53:09 -04002287 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2288 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2289 fprintf(stderr, "Could not set default DTLS version.\n");
2290 return false;
2291 }
2292
2293 if (ctx->min_version != TLS1_1_VERSION ||
2294 ctx->max_version != TLS1_2_VERSION) {
2295 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2296 ctx->min_version, ctx->max_version);
2297 return false;
2298 }
2299
David Benjamin2dc02042016-09-19 19:57:37 -04002300 return true;
2301}
2302
David Benjamincb18ac22016-09-27 14:09:15 -04002303static bool TestVersions() {
2304 bssl::UniquePtr<X509> cert = GetTestCertificate();
2305 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2306 if (!cert || !key) {
2307 return false;
2308 }
2309
2310 for (bool is_dtls : std::vector<bool>{false, true}) {
2311 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2312 const char *name = is_dtls ? "DTLS" : "TLS";
2313 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2314 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2315 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2316 for (size_t i = 0; i < num_versions; i++) {
2317 uint16_t version = versions[i];
2318 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2319 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2320 bssl::UniquePtr<SSL> client, server;
2321 if (!server_ctx || !client_ctx ||
2322 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2323 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2324 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2325 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2326 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2327 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2328 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2329 server_ctx.get(), nullptr /* no session */)) {
2330 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2331 version);
2332 return false;
2333 }
2334
2335 if (SSL_version(client.get()) != version ||
2336 SSL_version(server.get()) != version) {
2337 fprintf(stderr,
2338 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2339 SSL_version(client.get()), SSL_version(server.get()), version);
2340 return false;
2341 }
2342 }
2343 }
2344
2345 return true;
2346}
2347
David Benjamin9ef31f02016-10-31 18:01:13 -04002348// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2349// selection callback.
2350static bool TestALPNCipherAvailable() {
2351 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2352
2353 bssl::UniquePtr<X509> cert = GetTestCertificate();
2354 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2355 if (!cert || !key) {
2356 return false;
2357 }
2358
2359 for (uint16_t version : kTLSVersions) {
2360 // SSL 3.0 lacks extensions.
2361 if (version == SSL3_VERSION) {
2362 continue;
2363 }
2364
2365 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2366 if (!ctx ||
2367 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2368 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2369 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2370 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2371 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2372 0) {
2373 return false;
2374 }
2375
2376 // The ALPN callback does not fail the handshake on error, so have the
2377 // callback write a boolean.
Adam Langleyfb73e972016-11-02 13:21:29 -07002378 std::pair<uint16_t, bool> callback_state(version, false);
David Benjamin9ef31f02016-10-31 18:01:13 -04002379 SSL_CTX_set_alpn_select_cb(
2380 ctx.get(),
2381 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2382 unsigned in_len, void *arg) -> int {
Adam Langleyfb73e972016-11-02 13:21:29 -07002383 auto state = reinterpret_cast<std::pair<uint16_t, bool>*>(arg);
2384 if (SSL_get_pending_cipher(ssl) != nullptr &&
2385 SSL_version(ssl) == state->first) {
2386 state->second = true;
2387 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002388 return SSL_TLSEXT_ERR_NOACK;
2389 },
Adam Langleyfb73e972016-11-02 13:21:29 -07002390 &callback_state);
David Benjamin9ef31f02016-10-31 18:01:13 -04002391
2392 bssl::UniquePtr<SSL> client, server;
2393 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2394 nullptr /* no session */)) {
2395 return false;
2396 }
2397
Adam Langleyfb73e972016-11-02 13:21:29 -07002398 if (!callback_state.second) {
David Benjamin9ef31f02016-10-31 18:01:13 -04002399 fprintf(stderr,
2400 "%x: The pending cipher was not known in the ALPN callback.\n",
2401 version);
2402 return false;
2403 }
2404 }
2405
2406 return true;
2407}
2408
David Benjamin1d128f32015-09-08 17:41:40 -04002409int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002410 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002411
Adam Langley10f97f32016-07-12 08:09:33 -07002412 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002413 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002414 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2415 !TestSSL_SESSIONEncoding(kCustomSession) ||
2416 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2417 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2418 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2419 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002420 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002421 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2422 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2423 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2424 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2425 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2426 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2427 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2428 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2429 !TestCipherGetRFCName() ||
2430 !TestPaddingExtension() ||
2431 !TestClientCAList() ||
2432 !TestInternalSessionCache() ||
Steven Valdez2c62fe92016-10-14 12:08:12 -04002433 !TestSequenceNumber() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002434 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002435 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002436 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002437 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002438 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002439 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002440 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002441 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002442 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002443 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002444 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002445 !TestSetVersion() ||
David Benjamin9ef31f02016-10-31 18:01:13 -04002446 !TestVersions() ||
2447 !TestALPNCipherAvailable()) {
Brian Smith83a82982015-04-09 16:21:10 -10002448 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002449 return 1;
2450 }
2451
David Benjamin2e521212014-07-16 14:37:51 -04002452 printf("PASS\n");
2453 return 0;
2454}