blob: b74e51e1c28f76a29be2dbb96bcfedb4a1c0579c [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040026#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040027#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040028#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040029#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050030#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040031#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040033#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050034#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035
Steven Valdez87eab492016-06-27 16:34:59 -040036#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040037#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020038#include "../crypto/test/test_util.h"
39
David Benjamin721e8b72016-08-03 13:13:17 -040040#if defined(OPENSSL_WINDOWS)
41/* Windows defines struct timeval in winsock2.h. */
42OPENSSL_MSVC_PRAGMA(warning(push, 3))
43#include <winsock2.h>
44OPENSSL_MSVC_PRAGMA(warning(pop))
45#else
46#include <sys/time.h>
47#endif
48
David Benjamin1d77e562015-03-22 17:22:08 -040049
50struct ExpectedCipher {
51 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040052 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040053};
David Benjaminbb0a17c2014-09-20 15:35:39 -040054
David Benjamin1d77e562015-03-22 17:22:08 -040055struct CipherTest {
56 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040057 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050058 // The list of expected ciphers, in order.
59 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040060};
David Benjaminbb0a17c2014-09-20 15:35:39 -040061
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010062struct CurveTest {
63 // The rule string to apply.
64 const char *rule;
65 // The list of expected curves, in order.
66 std::vector<uint16_t> expected;
67};
68
David Benjaminfb974e62015-12-16 19:34:22 -050069static const CipherTest kCipherTests[] = {
70 // Selecting individual ciphers should work.
71 {
72 "ECDHE-ECDSA-CHACHA20-POLY1305:"
73 "ECDHE-RSA-CHACHA20-POLY1305:"
74 "ECDHE-ECDSA-AES128-GCM-SHA256:"
75 "ECDHE-RSA-AES128-GCM-SHA256",
76 {
77 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
78 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
80 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
81 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
82 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
83 },
84 },
85 // + reorders selected ciphers to the end, keeping their relative order.
86 {
87 "ECDHE-ECDSA-CHACHA20-POLY1305:"
88 "ECDHE-RSA-CHACHA20-POLY1305:"
89 "ECDHE-ECDSA-AES128-GCM-SHA256:"
90 "ECDHE-RSA-AES128-GCM-SHA256:"
91 "+aRSA",
92 {
93 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
96 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
97 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
98 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
99 },
100 },
101 // ! banishes ciphers from future selections.
102 {
103 "!aRSA:"
104 "ECDHE-ECDSA-CHACHA20-POLY1305:"
105 "ECDHE-RSA-CHACHA20-POLY1305:"
106 "ECDHE-ECDSA-AES128-GCM-SHA256:"
107 "ECDHE-RSA-AES128-GCM-SHA256",
108 {
109 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
110 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
111 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
112 },
113 },
114 // Multiple masks can be ANDed in a single rule.
115 {
116 "kRSA+AESGCM+AES128",
117 {
118 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
119 },
120 },
121 // - removes selected ciphers, but preserves their order for future
122 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
123 // ECDHE_RSA.
124 {
125 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
126 "AESGCM+AES128+aRSA",
127 {
128 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
129 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
130 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
131 },
132 },
133 // Unknown selectors are no-ops.
134 {
135 "ECDHE-ECDSA-CHACHA20-POLY1305:"
136 "ECDHE-RSA-CHACHA20-POLY1305:"
137 "ECDHE-ECDSA-AES128-GCM-SHA256:"
138 "ECDHE-RSA-AES128-GCM-SHA256:"
139 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
140 {
141 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
142 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
144 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
145 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
146 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
147 },
148 },
149 // Square brackets specify equi-preference groups.
150 {
151 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
152 "[ECDHE-RSA-CHACHA20-POLY1305]:"
153 "ECDHE-RSA-AES128-GCM-SHA256",
154 {
155 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
157 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
158 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
159 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
160 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
161 },
162 },
163 // @STRENGTH performs a stable strength-sort of the selected ciphers and
164 // only the selected ciphers.
165 {
166 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500168 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
169 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700170 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500171 // Select ECDHE ones and sort them by strength. Ties should resolve
172 // based on the order above.
173 "kECDHE:@STRENGTH:-ALL:"
174 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
175 // by strength. Then RSA, backwards by strength.
176 "aRSA",
177 {
178 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
179 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
180 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500181 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500182 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
183 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
184 },
185 },
186 // Exact ciphers may not be used in multi-part rules; they are treated
187 // as unknown aliases.
188 {
189 "ECDHE-ECDSA-AES128-GCM-SHA256:"
190 "ECDHE-RSA-AES128-GCM-SHA256:"
191 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
192 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
193 {
194 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
195 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
196 },
197 },
198 // SSLv3 matches everything that existed before TLS 1.2.
199 {
200 "AES128-SHA:AES128-SHA256:!SSLv3",
201 {
202 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
203 },
204 },
205 // TLSv1.2 matches everything added in TLS 1.2.
206 {
207 "AES128-SHA:AES128-SHA256:!TLSv1.2",
208 {
209 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
210 },
211 },
212 // The two directives have no intersection.
213 {
214 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
215 {
216 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
217 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
218 },
219 },
220 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
221 // name and not an alias. It may not be used in a multipart rule. (That the
222 // shared name works is covered by the standard tests.)
223 {
224 "ECDHE-ECDSA-CHACHA20-POLY1305:"
225 "ECDHE-RSA-CHACHA20-POLY1305:"
226 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
227 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
228 {
229 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
230 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
231 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
232 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
233 },
234 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235};
236
237static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400238 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400239 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
240 "RSA]",
241 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400242 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400243 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400244 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400245 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400246 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400247 "",
248 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400249 // COMPLEMENTOFDEFAULT is empty.
250 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400251 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400252 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400253 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
255 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
256 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
257 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700258 // Opcode supplied, but missing selector.
259 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400260};
261
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700262static const char *kMustNotIncludeNull[] = {
263 "ALL",
264 "DEFAULT",
265 "ALL:!eNULL",
266 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500267 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700268 "FIPS",
269 "SHA",
270 "SHA1",
271 "RSA",
272 "SSLv3",
273 "TLSv1",
274 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700275};
276
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100277static const CurveTest kCurveTests[] = {
278 {
279 "P-256",
280 { SSL_CURVE_SECP256R1 },
281 },
282 {
283 "P-256:P-384:P-521:X25519",
284 {
285 SSL_CURVE_SECP256R1,
286 SSL_CURVE_SECP384R1,
287 SSL_CURVE_SECP521R1,
288 SSL_CURVE_X25519,
289 },
290 },
291};
292
293static const char *kBadCurvesLists[] = {
294 "",
295 ":",
296 "::",
297 "P-256::X25519",
298 "RSA:P-256",
299 "P-256:RSA",
300 "X25519:P-256:",
301 ":X25519:P-256",
302};
303
David Benjamin1d77e562015-03-22 17:22:08 -0400304static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
305 bool in_group = false;
306 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400307 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
308 if (!in_group && list->in_group_flags[i]) {
309 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400310 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400311 }
312 fprintf(stderr, "\t");
313 if (in_group) {
314 fprintf(stderr, " ");
315 }
316 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
317 if (in_group && !list->in_group_flags[i]) {
318 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400319 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400320 }
321 }
322}
323
David Benjaminfb974e62015-12-16 19:34:22 -0500324static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700325 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400326 if (!ctx) {
327 return false;
David Benjamin65226252015-02-05 16:49:47 -0500328 }
329
David Benjaminfb974e62015-12-16 19:34:22 -0500330 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
331 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400332 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400333 }
334
David Benjamin1d77e562015-03-22 17:22:08 -0400335 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500336 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
337 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
338 PrintCipherPreferenceList(ctx->cipher_list);
339 return false;
340 }
341
342 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400343 const SSL_CIPHER *cipher =
344 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500345 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
346 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
347 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400348 PrintCipherPreferenceList(ctx->cipher_list);
349 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400350 }
351 }
352
David Benjamin1d77e562015-03-22 17:22:08 -0400353 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354}
355
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700356static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700357 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700358 if (!ctx) {
359 return false;
360 }
361 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
362 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
363 return false;
364 }
365 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
366 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
367 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
368 return false;
369 }
370 }
371 return true;
372}
373
David Benjamin1d77e562015-03-22 17:22:08 -0400374static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500375 for (const CipherTest &test : kCipherTests) {
376 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400377 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400378 }
379 }
380
David Benjaminfb974e62015-12-16 19:34:22 -0500381 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700382 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400383 if (!ctx) {
384 return false;
David Benjamin65226252015-02-05 16:49:47 -0500385 }
David Benjaminfb974e62015-12-16 19:34:22 -0500386 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
387 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400388 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400389 }
390 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400391 }
392
David Benjaminfb974e62015-12-16 19:34:22 -0500393 for (const char *rule : kMustNotIncludeNull) {
394 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700395 return false;
396 }
397 }
398
David Benjamin1d77e562015-03-22 17:22:08 -0400399 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400400}
David Benjamin2e521212014-07-16 14:37:51 -0400401
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100402static bool TestCurveRule(const CurveTest &t) {
403 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
404 if (!ctx) {
405 return false;
406 }
407
408 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
409 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
410 return false;
411 }
412
413 // Compare the two lists.
414 if (ctx->supported_group_list_len != t.expected.size()) {
415 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
416 return false;
417 }
418
419 for (size_t i = 0; i < t.expected.size(); i++) {
420 if (t.expected[i] != ctx->supported_group_list[i]) {
421 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
422 return false;
423 }
424 }
425
426 return true;
427}
428
429static bool TestCurveRules() {
430 for (const CurveTest &test : kCurveTests) {
431 if (!TestCurveRule(test)) {
432 return false;
433 }
434 }
435
436 for (const char *rule : kBadCurvesLists) {
437 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
438 if (!ctx) {
439 return false;
440 }
441 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
442 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
443 return false;
444 }
445 ERR_clear_error();
446 }
447
448 return true;
449}
450
Adam Langley364f7a62016-12-12 10:51:00 -0800451// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700452static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800453 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700454 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
455 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
456 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
457 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
458 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
459 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
460 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
461 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
462 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
463 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
464 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
465 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
466 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
467 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
468 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
469 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
470 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
471 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
472 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
473 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
474 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
475 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
476 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
477 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
478 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
479 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
480 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
481 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
482 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800483 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700484
485// kCustomSession is a custom serialized SSL_SESSION generated by
486// filling in missing fields from |kOpenSSLSession|. This includes
487// providing |peer_sha256|, so |peer| is not serialized.
488static const char kCustomSession[] =
489 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
490 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
491 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
492 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
493 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
494 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
495 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
496 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
497
498// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
499static const char kBoringSSLSession[] =
500 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
501 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
502 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
503 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
504 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
505 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
506 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
507 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
508 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
509 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
510 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
511 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
512 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
513 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
514 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
515 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
516 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
517 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
518 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
519 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
520 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
521 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
522 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
523 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
524 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
525 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
526 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
527 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
528 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
529 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
530 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
531 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
532 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
533 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
534 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
535 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
536 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
537 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
538 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
539 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
540 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
541 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
542 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
543 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
544 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
545 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
546 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
547 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
548 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
549 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
550 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
551 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
552 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
553 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
554 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
555 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
556 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
557 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
558 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
559 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
560 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
561 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
562 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
563 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
564 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
565 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
566 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
567 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
568 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
569 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
570 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
571 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
572 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
573 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
574 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
575 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
576 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
577 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
578 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
579 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
580 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
581 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
582 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
583 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
584 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
585 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
586 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
587 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
588 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
589 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
590 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
591 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
592 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
593 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
594 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
595
596// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
597// the final (optional) element of |kCustomSession| with tag number 30.
598static const char kBadSessionExtraField[] =
599 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
600 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
601 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
602 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
603 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
604 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
605 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
606 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
607
608// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
609// the version of |kCustomSession| with 2.
610static const char kBadSessionVersion[] =
611 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
612 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
613 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
614 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
615 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
616 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
617 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
618 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
619
620// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
621// appended.
622static const char kBadSessionTrailingData[] =
623 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
624 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
625 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
626 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
627 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
628 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
629 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
630 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
631
David Benjamin1d77e562015-03-22 17:22:08 -0400632static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400633 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400634 if (!EVP_DecodedLength(&len, strlen(in))) {
635 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400636 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400637 }
638
David Benjamin1d77e562015-03-22 17:22:08 -0400639 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800640 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400641 strlen(in))) {
642 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400643 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400644 }
David Benjamin1d77e562015-03-22 17:22:08 -0400645 out->resize(len);
646 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400647}
648
David Benjamin1d77e562015-03-22 17:22:08 -0400649static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400650 const uint8_t *cptr;
651 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400652
David Benjamin1d77e562015-03-22 17:22:08 -0400653 // Decode the input.
654 std::vector<uint8_t> input;
655 if (!DecodeBase64(&input, input_b64)) {
656 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400657 }
658
David Benjamin1d77e562015-03-22 17:22:08 -0400659 // Verify the SSL_SESSION decodes.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800660 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400661 if (!session) {
662 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400663 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400664 }
665
David Benjamin1d77e562015-03-22 17:22:08 -0400666 // Verify the SSL_SESSION encoding round-trips.
667 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700668 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400669 uint8_t *encoded_raw;
670 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400671 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400672 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400673 }
David Benjamin1d77e562015-03-22 17:22:08 -0400674 encoded.reset(encoded_raw);
675 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800676 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400677 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200678 hexdump(stderr, "Before: ", input.data(), input.size());
679 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400680 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400681 }
David Benjamin3cac4502014-10-21 01:46:30 -0400682
David Benjaminfd67aa82015-06-15 19:41:48 -0400683 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800684 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400685 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800686 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400687 fprintf(stderr, "d2i_SSL_SESSION failed\n");
688 return false;
689 }
690
David Benjamin1d77e562015-03-22 17:22:08 -0400691 // Verify the SSL_SESSION encoding round-trips via the legacy API.
692 int len = i2d_SSL_SESSION(session.get(), NULL);
693 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400694 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400695 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400696 }
697
David Benjamin1d77e562015-03-22 17:22:08 -0400698 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
699 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400700 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400701 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400702 }
David Benjamin1d77e562015-03-22 17:22:08 -0400703
704 ptr = encoded.get();
705 len = i2d_SSL_SESSION(session.get(), &ptr);
706 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400707 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400708 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400709 }
David Benjamin1d77e562015-03-22 17:22:08 -0400710 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400711 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400712 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400713 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800714 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400715 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400716 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400717 }
718
David Benjamin1d77e562015-03-22 17:22:08 -0400719 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400720}
721
David Benjaminf297e022015-05-28 19:55:29 -0400722static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
723 std::vector<uint8_t> input;
724 if (!DecodeBase64(&input, input_b64)) {
725 return false;
726 }
727
728 // Verify that the SSL_SESSION fails to decode.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800729 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400730 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400732 return false;
733 }
734 ERR_clear_error();
735 return true;
736}
737
David Benjamin10e664b2016-06-20 22:20:47 -0400738static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400739 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700740 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400741 if (!ctx) {
742 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500743 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400744 if (ctx->min_version != min_version || ctx->max_version != max_version) {
745 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
746 ctx->min_version, ctx->max_version, min_version, max_version);
747 return false;
748 }
749 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500750}
751
David Benjamin1d77e562015-03-22 17:22:08 -0400752static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500753 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
754 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400755 return false;
David Benjamin65226252015-02-05 16:49:47 -0500756 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700757 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400758 if (!rfc_name) {
759 return false;
760 }
David Benjamin67be0482015-04-20 16:19:00 -0400761 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return true;
David Benjamin65226252015-02-05 16:49:47 -0500763}
764
765typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500766 int id;
David Benjamin65226252015-02-05 16:49:47 -0500767 const char *rfc_name;
768} CIPHER_RFC_NAME_TEST;
769
770static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400771 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
772 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
773 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
774 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
775 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
776 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
777 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
778 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
779 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
780 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
781 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
782 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
783 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
784 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
785 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
786 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
787 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
788 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
789 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
790 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
791 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
792 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
793
794 // These names are non-standard:
795 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
796 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
797 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
798 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500799};
800
David Benjamin1d77e562015-03-22 17:22:08 -0400801static bool TestCipherGetRFCName(void) {
802 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400803 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500804 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400805 std::string rfc_name;
806 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
807 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
808 return false;
David Benjamin65226252015-02-05 16:49:47 -0500809 }
David Benjamin1d77e562015-03-22 17:22:08 -0400810 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500811 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400812 rfc_name.c_str(), test->rfc_name);
813 return false;
David Benjamin65226252015-02-05 16:49:47 -0500814 }
David Benjamin65226252015-02-05 16:49:47 -0500815 }
David Benjamin1d77e562015-03-22 17:22:08 -0400816 return true;
David Benjamin65226252015-02-05 16:49:47 -0500817}
818
Steven Valdeza833c352016-11-01 13:39:36 -0400819// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
820// version and ticket length or nullptr on failure.
821static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
822 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400823 std::vector<uint8_t> der;
824 if (!DecodeBase64(&der, kOpenSSLSession)) {
825 return nullptr;
826 }
Steven Valdeza833c352016-11-01 13:39:36 -0400827 bssl::UniquePtr<SSL_SESSION> session(
828 SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400829 if (!session) {
830 return nullptr;
831 }
832
Steven Valdeza833c352016-11-01 13:39:36 -0400833 session->ssl_version = version;
834
David Benjamin422fe082015-07-21 22:03:43 -0400835 // Swap out the ticket for a garbage one.
836 OPENSSL_free(session->tlsext_tick);
837 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
838 if (session->tlsext_tick == nullptr) {
839 return nullptr;
840 }
841 memset(session->tlsext_tick, 'a', ticket_len);
842 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400843
844 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500845#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
846 session->time = 1234;
847#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400848 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500849#endif
David Benjamin422fe082015-07-21 22:03:43 -0400850 return session;
851}
852
David Benjaminafc64de2016-07-19 17:12:41 +0200853static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700854 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200855 if (!bio) {
856 return false;
857 }
858 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400859 BIO_up_ref(bio.get());
860 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200861 int ret = SSL_connect(ssl);
862 if (ret > 0) {
863 // SSL_connect should fail without a BIO to write to.
864 return false;
865 }
866 ERR_clear_error();
867
868 const uint8_t *client_hello;
869 size_t client_hello_len;
870 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
871 return false;
872 }
873 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
874 return true;
875}
876
Steven Valdeza833c352016-11-01 13:39:36 -0400877// GetClientHelloLen creates a client SSL connection with the specified version
878// and ticket length. It returns the length of the ClientHello, not including
879// the record header, on success and zero on error.
880static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
881 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700882 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400883 bssl::UniquePtr<SSL_SESSION> session =
884 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400885 if (!ctx || !session) {
886 return 0;
887 }
Steven Valdeza833c352016-11-01 13:39:36 -0400888
889 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700890 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400891 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400892 !SSL_set_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
893 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400894 return 0;
895 }
Steven Valdeza833c352016-11-01 13:39:36 -0400896
David Benjaminafc64de2016-07-19 17:12:41 +0200897 std::vector<uint8_t> client_hello;
898 if (!GetClientHello(ssl.get(), &client_hello) ||
899 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400900 return 0;
901 }
Steven Valdeza833c352016-11-01 13:39:36 -0400902
David Benjaminafc64de2016-07-19 17:12:41 +0200903 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400904}
905
906struct PaddingTest {
907 size_t input_len, padded_len;
908};
909
910static const PaddingTest kPaddingTests[] = {
911 // ClientHellos of length below 0x100 do not require padding.
912 {0xfe, 0xfe},
913 {0xff, 0xff},
914 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
915 {0x100, 0x200},
916 {0x123, 0x200},
917 {0x1fb, 0x200},
918 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
919 // padding extension takes a minimum of four bytes plus one required content
920 // byte. (To work around yet more server bugs, we avoid empty final
921 // extensions.)
922 {0x1fc, 0x201},
923 {0x1fd, 0x202},
924 {0x1fe, 0x203},
925 {0x1ff, 0x204},
926 // Finally, larger ClientHellos need no padding.
927 {0x200, 0x200},
928 {0x201, 0x201},
929};
930
Steven Valdeza833c352016-11-01 13:39:36 -0400931static bool TestPaddingExtension(uint16_t max_version,
932 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400933 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400934 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400935 if (base_len == 0) {
936 return false;
937 }
938
939 for (const PaddingTest &test : kPaddingTests) {
940 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400941 fprintf(stderr,
942 "Baseline ClientHello too long (max_version = %04x, "
943 "session_version = %04x).\n",
944 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400945 return false;
946 }
947
Steven Valdeza833c352016-11-01 13:39:36 -0400948 size_t padded_len = GetClientHelloLen(max_version, session_version,
949 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400950 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400951 fprintf(stderr,
952 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
953 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400954 static_cast<unsigned>(test.input_len),
955 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400956 static_cast<unsigned>(test.padded_len), max_version,
957 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400958 return false;
959 }
960 }
Steven Valdeza833c352016-11-01 13:39:36 -0400961
David Benjamin422fe082015-07-21 22:03:43 -0400962 return true;
963}
964
David Benjamin1d128f32015-09-08 17:41:40 -0400965// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
966// before configuring as a server.
967static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700968 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400969 if (!ctx) {
970 return false;
971 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700972 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400973 if (!ssl) {
974 return false;
975 }
976
977 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
978 if (stack == nullptr) {
979 return false;
980 }
981 // |SSL_set_client_CA_list| takes ownership.
982 SSL_set_client_CA_list(ssl.get(), stack);
983
984 return SSL_get_client_CA_list(ssl.get()) == stack;
985}
986
David Benjamin0f653952015-10-18 14:28:01 -0400987static void AppendSession(SSL_SESSION *session, void *arg) {
988 std::vector<SSL_SESSION*> *out =
989 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
990 out->push_back(session);
991}
992
993// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
994// order.
995static bool ExpectCache(SSL_CTX *ctx,
996 const std::vector<SSL_SESSION*> &expected) {
997 // Check the linked list.
998 SSL_SESSION *ptr = ctx->session_cache_head;
999 for (SSL_SESSION *session : expected) {
1000 if (ptr != session) {
1001 return false;
1002 }
1003 // TODO(davidben): This is an absurd way to denote the end of the list.
1004 if (ptr->next ==
1005 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1006 ptr = nullptr;
1007 } else {
1008 ptr = ptr->next;
1009 }
1010 }
1011 if (ptr != nullptr) {
1012 return false;
1013 }
1014
1015 // Check the hash table.
1016 std::vector<SSL_SESSION*> actual, expected_copy;
1017 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1018 expected_copy = expected;
1019
1020 std::sort(actual.begin(), actual.end());
1021 std::sort(expected_copy.begin(), expected_copy.end());
1022
1023 return actual == expected_copy;
1024}
1025
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001026static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1027 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001028 if (!ret) {
1029 return nullptr;
1030 }
1031
1032 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1033 memset(ret->session_id, 0, ret->session_id_length);
1034 memcpy(ret->session_id, &number, sizeof(number));
1035 return ret;
1036}
1037
David Benjamin0f653952015-10-18 14:28:01 -04001038// Test that the internal session cache behaves as expected.
1039static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001040 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001041 if (!ctx) {
1042 return false;
1043 }
1044
1045 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001046 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001047 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001048 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001049 if (!session) {
1050 return false;
1051 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001052 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001053 }
1054
1055 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1056
1057 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001058 for (const auto &session : sessions) {
1059 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001060 return false;
1061 }
1062 }
1063
1064 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001065 std::vector<SSL_SESSION*> expected = {
1066 sessions[9].get(),
1067 sessions[8].get(),
1068 sessions[7].get(),
1069 sessions[6].get(),
1070 sessions[5].get(),
1071 };
David Benjamin0f653952015-10-18 14:28:01 -04001072 if (!ExpectCache(ctx.get(), expected)) {
1073 return false;
1074 }
1075
1076 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001077 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001078 !ExpectCache(ctx.get(), expected)) {
1079 return false;
1080 }
1081
1082 // Although collisions should be impossible (256-bit session IDs), the cache
1083 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001084 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001085 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1086 return false;
1087 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001088 expected = {
1089 collision.get(),
1090 sessions[9].get(),
1091 sessions[8].get(),
1092 sessions[6].get(),
1093 sessions[5].get(),
1094 };
David Benjamin0f653952015-10-18 14:28:01 -04001095 if (!ExpectCache(ctx.get(), expected)) {
1096 return false;
1097 }
1098
1099 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001100 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001101 return false;
1102 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001103 expected = {
1104 collision.get(),
1105 sessions[9].get(),
1106 sessions[8].get(),
1107 sessions[5].get(),
1108 };
David Benjamin0f653952015-10-18 14:28:01 -04001109 if (!ExpectCache(ctx.get(), expected)) {
1110 return false;
1111 }
1112
1113 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001114 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1115 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001116 !ExpectCache(ctx.get(), expected)) {
1117 return false;
1118 }
1119
1120 return true;
1121}
1122
David Benjaminde942382016-02-11 12:02:01 -05001123static uint16_t EpochFromSequence(uint64_t seq) {
1124 return static_cast<uint16_t>(seq >> 48);
1125}
1126
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001127static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001128 static const char kCertPEM[] =
1129 "-----BEGIN CERTIFICATE-----\n"
1130 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1131 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1132 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1133 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1134 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1135 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1136 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1137 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1138 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1139 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1140 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1141 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1142 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1143 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1145 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001146}
1147
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001148static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001149 static const char kKeyPEM[] =
1150 "-----BEGIN RSA PRIVATE KEY-----\n"
1151 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1152 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1153 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1154 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1155 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1156 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1157 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1158 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1159 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1160 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1161 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1162 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1163 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1164 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001165 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1166 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001167 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1168}
1169
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001170static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001171 static const char kCertPEM[] =
1172 "-----BEGIN CERTIFICATE-----\n"
1173 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1174 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1175 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1176 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1177 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1178 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1179 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1180 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1181 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1182 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1183 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001184 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1185 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001186}
1187
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001188static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001189 static const char kKeyPEM[] =
1190 "-----BEGIN PRIVATE KEY-----\n"
1191 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1192 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1193 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1194 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001195 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1196 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001197 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1198}
1199
David Benjaminb79cc842016-12-07 15:57:14 -05001200static bool CompleteHandshakes(SSL *client, SSL *server) {
1201 // Drive both their handshakes to completion.
1202 for (;;) {
1203 int client_ret = SSL_do_handshake(client);
1204 int client_err = SSL_get_error(client, client_ret);
1205 if (client_err != SSL_ERROR_NONE &&
1206 client_err != SSL_ERROR_WANT_READ &&
1207 client_err != SSL_ERROR_WANT_WRITE) {
1208 fprintf(stderr, "Client error: %d\n", client_err);
1209 return false;
1210 }
1211
1212 int server_ret = SSL_do_handshake(server);
1213 int server_err = SSL_get_error(server, server_ret);
1214 if (server_err != SSL_ERROR_NONE &&
1215 server_err != SSL_ERROR_WANT_READ &&
1216 server_err != SSL_ERROR_WANT_WRITE) {
1217 fprintf(stderr, "Server error: %d\n", server_err);
1218 return false;
1219 }
1220
1221 if (client_ret == 1 && server_ret == 1) {
1222 break;
1223 }
1224 }
1225
1226 return true;
1227}
1228
1229static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1230 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001231 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1232 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001233 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001234 if (!client || !server) {
1235 return false;
1236 }
1237 SSL_set_connect_state(client.get());
1238 SSL_set_accept_state(server.get());
1239
David Benjamina20e5352016-08-02 19:09:41 -04001240 SSL_set_session(client.get(), session);
1241
David Benjaminde942382016-02-11 12:02:01 -05001242 BIO *bio1, *bio2;
1243 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1244 return false;
1245 }
1246 // SSL_set_bio takes ownership.
1247 SSL_set_bio(client.get(), bio1, bio1);
1248 SSL_set_bio(server.get(), bio2, bio2);
1249
David Benjaminb79cc842016-12-07 15:57:14 -05001250 if (!CompleteHandshakes(client.get(), server.get())) {
1251 return false;
David Benjaminde942382016-02-11 12:02:01 -05001252 }
1253
David Benjamin686bb192016-05-10 15:15:41 -04001254 *out_client = std::move(client);
1255 *out_server = std::move(server);
1256 return true;
1257}
1258
David Benjamin0fef3052016-11-18 15:11:10 +09001259static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1260 uint16_t version) {
1261 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1262 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1263 if (!server_ctx || !client_ctx ||
1264 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1265 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1266 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1267 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1268 return false;
1269 }
David Benjamin686bb192016-05-10 15:15:41 -04001270
David Benjamin0fef3052016-11-18 15:11:10 +09001271 bssl::UniquePtr<X509> cert = GetTestCertificate();
1272 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1273 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1274 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1275 return false;
1276 }
David Benjamin686bb192016-05-10 15:15:41 -04001277
David Benjamin0fef3052016-11-18 15:11:10 +09001278 bssl::UniquePtr<SSL> client, server;
1279 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1280 server_ctx.get(), nullptr /* no session */)) {
1281 return false;
1282 }
David Benjamin686bb192016-05-10 15:15:41 -04001283
David Benjamin0fef3052016-11-18 15:11:10 +09001284 // Drain any post-handshake messages to ensure there are no unread records
1285 // on either end.
1286 uint8_t byte = 0;
1287 if (SSL_read(client.get(), &byte, 1) > 0 ||
1288 SSL_read(server.get(), &byte, 1) > 0) {
1289 fprintf(stderr, "Received unexpected data.\n");
1290 return false;
1291 }
David Benjaminde942382016-02-11 12:02:01 -05001292
David Benjamin0fef3052016-11-18 15:11:10 +09001293 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1294 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1295 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1296 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001297
David Benjamin0fef3052016-11-18 15:11:10 +09001298 if (is_dtls) {
1299 // Both client and server must be at epoch 1.
1300 if (EpochFromSequence(client_read_seq) != 1 ||
1301 EpochFromSequence(client_write_seq) != 1 ||
1302 EpochFromSequence(server_read_seq) != 1 ||
1303 EpochFromSequence(server_write_seq) != 1) {
1304 fprintf(stderr, "Bad epochs.\n");
1305 return false;
David Benjaminde942382016-02-11 12:02:01 -05001306 }
David Benjamin0fef3052016-11-18 15:11:10 +09001307
1308 // The next record to be written should exceed the largest received.
1309 if (client_write_seq <= server_read_seq ||
1310 server_write_seq <= client_read_seq) {
1311 fprintf(stderr, "Inconsistent sequence numbers.\n");
1312 return false;
1313 }
1314 } else {
1315 // The next record to be written should equal the next to be received.
1316 if (client_write_seq != server_read_seq ||
1317 server_write_seq != client_read_seq) {
1318 fprintf(stderr, "Inconsistent sequence numbers.\n");
1319 return false;
1320 }
1321 }
1322
1323 // Send a record from client to server.
1324 if (SSL_write(client.get(), &byte, 1) != 1 ||
1325 SSL_read(server.get(), &byte, 1) != 1) {
1326 fprintf(stderr, "Could not send byte.\n");
1327 return false;
1328 }
1329
1330 // The client write and server read sequence numbers should have
1331 // incremented.
1332 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1333 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1334 fprintf(stderr, "Sequence numbers did not increment.\n");
1335 return false;
David Benjaminde942382016-02-11 12:02:01 -05001336 }
1337
1338 return true;
1339}
1340
David Benjamin68f37b72016-11-18 15:14:42 +09001341static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1342 uint16_t version) {
1343 // SSL_shutdown is a no-op in DTLS.
1344 if (is_dtls) {
1345 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001346 }
1347
David Benjamin68f37b72016-11-18 15:14:42 +09001348 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1349 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001350 bssl::UniquePtr<X509> cert = GetTestCertificate();
1351 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001352 if (!client_ctx || !server_ctx || !cert || !key ||
1353 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1354 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1355 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1356 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001357 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1358 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1359 return false;
1360 }
1361
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001362 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001363 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001364 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001365 return false;
1366 }
1367
1368 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1369 // one side has shut down.
1370 if (SSL_shutdown(client.get()) != 0) {
1371 fprintf(stderr, "Could not shutdown.\n");
1372 return false;
1373 }
1374
1375 // Reading from the server should consume the EOF.
1376 uint8_t byte;
1377 if (SSL_read(server.get(), &byte, 1) != 0 ||
1378 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1379 fprintf(stderr, "Connection was not shut down cleanly.\n");
1380 return false;
1381 }
1382
1383 // However, the server may continue to write data and then shut down the
1384 // connection.
1385 byte = 42;
1386 if (SSL_write(server.get(), &byte, 1) != 1 ||
1387 SSL_read(client.get(), &byte, 1) != 1 ||
1388 byte != 42) {
1389 fprintf(stderr, "Could not send byte.\n");
1390 return false;
1391 }
1392
1393 // The server may then shutdown the connection.
1394 if (SSL_shutdown(server.get()) != 1 ||
1395 SSL_shutdown(client.get()) != 1) {
1396 fprintf(stderr, "Could not complete shutdown.\n");
1397 return false;
1398 }
1399
1400 return true;
1401}
David Benjamin68f37b72016-11-18 15:14:42 +09001402
Steven Valdez87eab492016-06-27 16:34:59 -04001403static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001404 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1405 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001406 if (!client_ctx || !server_ctx) {
1407 return false;
1408 }
1409
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001410 bssl::UniquePtr<X509> cert = GetTestCertificate();
1411 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001412 if (!cert || !key ||
1413 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1414 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1415 return false;
1416 }
1417
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001418 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001419 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001420 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001421 return false;
1422 }
1423
1424 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001425 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001426 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001427 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001428 }
David Benjamin4501bd52016-08-01 13:39:41 -04001429
Steven Valdez84b5c002016-08-25 16:30:58 -04001430 session1->not_resumable = 0;
1431
Steven Valdez87eab492016-06-27 16:34:59 -04001432 uint8_t *s0_bytes, *s1_bytes;
1433 size_t s0_len, s1_len;
1434
1435 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1436 return false;
1437 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001438 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001439
1440 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1441 return false;
1442 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001443 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001444
1445 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1446}
David Benjamin686bb192016-05-10 15:15:41 -04001447
David Benjamin5c0fb882016-06-14 14:03:51 -04001448static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1449 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1450 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1451 SSL_get_wfd(ssl), rfd, wfd);
1452 return false;
1453 }
1454
1455 // The wrapper BIOs are always equal when fds are equal, even if set
1456 // individually.
1457 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1458 fprintf(stderr, "rbio and wbio did not match.\n");
1459 return false;
1460 }
1461
1462 return true;
1463}
1464
1465static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001466 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001467 if (!ctx) {
1468 return false;
1469 }
1470
1471 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001472 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001473 if (!ssl ||
1474 !SSL_set_rfd(ssl.get(), 1) ||
1475 !SSL_set_wfd(ssl.get(), 2) ||
1476 !ExpectFDs(ssl.get(), 1, 2)) {
1477 return false;
1478 }
1479
1480 // Test setting the same FD.
1481 ssl.reset(SSL_new(ctx.get()));
1482 if (!ssl ||
1483 !SSL_set_fd(ssl.get(), 1) ||
1484 !ExpectFDs(ssl.get(), 1, 1)) {
1485 return false;
1486 }
1487
1488 // Test setting the same FD one side at a time.
1489 ssl.reset(SSL_new(ctx.get()));
1490 if (!ssl ||
1491 !SSL_set_rfd(ssl.get(), 1) ||
1492 !SSL_set_wfd(ssl.get(), 1) ||
1493 !ExpectFDs(ssl.get(), 1, 1)) {
1494 return false;
1495 }
1496
1497 // Test setting the same FD in the other order.
1498 ssl.reset(SSL_new(ctx.get()));
1499 if (!ssl ||
1500 !SSL_set_wfd(ssl.get(), 1) ||
1501 !SSL_set_rfd(ssl.get(), 1) ||
1502 !ExpectFDs(ssl.get(), 1, 1)) {
1503 return false;
1504 }
1505
David Benjamin5c0fb882016-06-14 14:03:51 -04001506 // Test changing the read FD partway through.
1507 ssl.reset(SSL_new(ctx.get()));
1508 if (!ssl ||
1509 !SSL_set_fd(ssl.get(), 1) ||
1510 !SSL_set_rfd(ssl.get(), 2) ||
1511 !ExpectFDs(ssl.get(), 2, 1)) {
1512 return false;
1513 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001514
1515 // Test changing the write FD partway through.
1516 ssl.reset(SSL_new(ctx.get()));
1517 if (!ssl ||
1518 !SSL_set_fd(ssl.get(), 1) ||
1519 !SSL_set_wfd(ssl.get(), 2) ||
1520 !ExpectFDs(ssl.get(), 1, 2)) {
1521 return false;
1522 }
1523
1524 // Test a no-op change to the read FD partway through.
1525 ssl.reset(SSL_new(ctx.get()));
1526 if (!ssl ||
1527 !SSL_set_fd(ssl.get(), 1) ||
1528 !SSL_set_rfd(ssl.get(), 1) ||
1529 !ExpectFDs(ssl.get(), 1, 1)) {
1530 return false;
1531 }
1532
1533 // Test a no-op change to the write FD partway through.
1534 ssl.reset(SSL_new(ctx.get()));
1535 if (!ssl ||
1536 !SSL_set_fd(ssl.get(), 1) ||
1537 !SSL_set_wfd(ssl.get(), 1) ||
1538 !ExpectFDs(ssl.get(), 1, 1)) {
1539 return false;
1540 }
1541
1542 // ASan builds will implicitly test that the internal |BIO| reference-counting
1543 // is correct.
1544
1545 return true;
1546}
1547
David Benjamin4501bd52016-08-01 13:39:41 -04001548static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001549 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001550 if (!ctx) {
1551 return false;
1552 }
1553
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001554 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1555 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001556 bio3(BIO_new(BIO_s_mem()));
1557 if (!ssl || !bio1 || !bio2 || !bio3) {
1558 return false;
1559 }
1560
1561 // SSL_set_bio takes one reference when the parameters are the same.
1562 BIO_up_ref(bio1.get());
1563 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1564
1565 // Repeating the call does nothing.
1566 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1567
1568 // It takes one reference each when the parameters are different.
1569 BIO_up_ref(bio2.get());
1570 BIO_up_ref(bio3.get());
1571 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1572
1573 // Repeating the call does nothing.
1574 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1575
1576 // It takes one reference when changing only wbio.
1577 BIO_up_ref(bio1.get());
1578 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1579
1580 // It takes one reference when changing only rbio and the two are different.
1581 BIO_up_ref(bio3.get());
1582 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1583
1584 // If setting wbio to rbio, it takes no additional references.
1585 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1586
1587 // From there, wbio may be switched to something else.
1588 BIO_up_ref(bio1.get());
1589 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1590
1591 // If setting rbio to wbio, it takes no additional references.
1592 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1593
1594 // From there, rbio may be switched to something else, but, for historical
1595 // reasons, it takes a reference to both parameters.
1596 BIO_up_ref(bio1.get());
1597 BIO_up_ref(bio2.get());
1598 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1599
1600 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1601 // is correct.
1602 return true;
1603}
1604
David Benjamin25490f22016-07-14 00:22:54 -04001605static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1606
David Benjamin0fef3052016-11-18 15:11:10 +09001607static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1608 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001609 bssl::UniquePtr<X509> cert = GetTestCertificate();
1610 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001611 if (!cert || !key) {
1612 return false;
1613 }
1614
David Benjamin0fef3052016-11-18 15:11:10 +09001615 // Configure both client and server to accept any certificate.
1616 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1617 if (!ctx ||
1618 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1619 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1620 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1621 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1622 return false;
1623 }
1624 SSL_CTX_set_verify(
1625 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1626 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001627
David Benjamin0fef3052016-11-18 15:11:10 +09001628 bssl::UniquePtr<SSL> client, server;
1629 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1630 nullptr /* no session */)) {
1631 return false;
1632 }
David Benjaminadd5e522016-07-14 00:33:24 -04001633
David Benjamin0fef3052016-11-18 15:11:10 +09001634 // Client and server should both see the leaf certificate.
1635 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1636 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1637 fprintf(stderr, "Server peer certificate did not match.\n");
1638 return false;
1639 }
David Benjaminadd5e522016-07-14 00:33:24 -04001640
David Benjamin0fef3052016-11-18 15:11:10 +09001641 peer.reset(SSL_get_peer_certificate(client.get()));
1642 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1643 fprintf(stderr, "Client peer certificate did not match.\n");
1644 return false;
1645 }
David Benjaminadd5e522016-07-14 00:33:24 -04001646
David Benjamin0fef3052016-11-18 15:11:10 +09001647 // However, for historical reasons, the chain includes the leaf on the
1648 // client, but does not on the server.
1649 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1650 fprintf(stderr, "Client peer chain was incorrect.\n");
1651 return false;
1652 }
David Benjaminadd5e522016-07-14 00:33:24 -04001653
David Benjamin0fef3052016-11-18 15:11:10 +09001654 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1655 fprintf(stderr, "Server peer chain was incorrect.\n");
1656 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001657 }
1658
1659 return true;
1660}
1661
David Benjamin0fef3052016-11-18 15:11:10 +09001662static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1663 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001664 bssl::UniquePtr<X509> cert = GetTestCertificate();
1665 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001666 if (!cert || !key) {
1667 return false;
1668 }
1669
1670 uint8_t *cert_der = NULL;
1671 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1672 if (cert_der_len < 0) {
1673 return false;
1674 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001675 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001676
1677 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1678 SHA256(cert_der, cert_der_len, cert_sha256);
1679
David Benjamin0fef3052016-11-18 15:11:10 +09001680 // Configure both client and server to accept any certificate, but the
1681 // server must retain only the SHA-256 of the peer.
1682 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1683 if (!ctx ||
1684 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1685 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1686 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1687 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1688 return false;
1689 }
1690 SSL_CTX_set_verify(
1691 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1692 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1693 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001694
David Benjamin0fef3052016-11-18 15:11:10 +09001695 bssl::UniquePtr<SSL> client, server;
1696 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1697 nullptr /* no session */)) {
1698 return false;
1699 }
David Benjamin25490f22016-07-14 00:22:54 -04001700
David Benjamin0fef3052016-11-18 15:11:10 +09001701 // The peer certificate has been dropped.
1702 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1703 if (peer) {
1704 fprintf(stderr, "Peer certificate was retained.\n");
1705 return false;
1706 }
David Benjamin25490f22016-07-14 00:22:54 -04001707
David Benjamin0fef3052016-11-18 15:11:10 +09001708 SSL_SESSION *session = SSL_get_session(server.get());
1709 if (!session->peer_sha256_valid) {
1710 fprintf(stderr, "peer_sha256_valid was not set.\n");
1711 return false;
1712 }
David Benjamin25490f22016-07-14 00:22:54 -04001713
David Benjamin0fef3052016-11-18 15:11:10 +09001714 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1715 fprintf(stderr, "peer_sha256 did not match.\n");
1716 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001717 }
1718
1719 return true;
1720}
1721
David Benjaminafc64de2016-07-19 17:12:41 +02001722static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1723 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001724 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001725 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001726 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001727 // Our default cipher list varies by CPU capabilities, so manually place
1728 // the ChaCha20 ciphers in front.
1729 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001730 return false;
1731 }
David Benjamin2dc02042016-09-19 19:57:37 -04001732
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001733 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001734 if (!ssl) {
1735 return false;
1736 }
1737 std::vector<uint8_t> client_hello;
1738 if (!GetClientHello(ssl.get(), &client_hello)) {
1739 return false;
1740 }
1741
1742 // Zero the client_random.
1743 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1744 1 + 3 + // handshake message header
1745 2; // client_version
1746 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1747 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1748 return false;
1749 }
1750 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1751
1752 if (client_hello.size() != expected_len ||
1753 memcmp(client_hello.data(), expected, expected_len) != 0) {
1754 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1755 fprintf(stderr, "Got:\n\t");
1756 for (size_t i = 0; i < client_hello.size(); i++) {
1757 fprintf(stderr, "0x%02x, ", client_hello[i]);
1758 }
1759 fprintf(stderr, "\nWanted:\n\t");
1760 for (size_t i = 0; i < expected_len; i++) {
1761 fprintf(stderr, "0x%02x, ", expected[i]);
1762 }
1763 fprintf(stderr, "\n");
1764 return false;
1765 }
1766
1767 return true;
1768}
1769
1770// Tests that our ClientHellos do not change unexpectedly.
1771static bool TestClientHello() {
1772 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001773 0x16,
1774 0x03, 0x00,
1775 0x00, 0x3f,
1776 0x01,
1777 0x00, 0x00, 0x3b,
1778 0x03, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1783 0x00,
1784 0x00, 0x14,
1785 0xc0, 0x09,
1786 0xc0, 0x13,
1787 0x00, 0x33,
1788 0xc0, 0x0a,
1789 0xc0, 0x14,
1790 0x00, 0x39,
1791 0x00, 0x2f,
1792 0x00, 0x35,
1793 0x00, 0x0a,
1794 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001795 };
1796 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1797 sizeof(kSSL3ClientHello))) {
1798 return false;
1799 }
1800
1801 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001802 0x16,
1803 0x03, 0x01,
1804 0x00, 0x5e,
1805 0x01,
1806 0x00, 0x00, 0x5a,
1807 0x03, 0x01,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00,
1813 0x00, 0x12,
1814 0xc0, 0x09,
1815 0xc0, 0x13,
1816 0x00, 0x33,
1817 0xc0, 0x0a,
1818 0xc0, 0x14,
1819 0x00, 0x39,
1820 0x00, 0x2f,
1821 0x00, 0x35,
1822 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001823 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1824 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1825 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1826 };
1827 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1828 sizeof(kTLS1ClientHello))) {
1829 return false;
1830 }
1831
1832 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001833 0x16,
1834 0x03, 0x01,
1835 0x00, 0x5e,
1836 0x01,
1837 0x00, 0x00, 0x5a,
1838 0x03, 0x02,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00,
1844 0x00, 0x12,
1845 0xc0, 0x09,
1846 0xc0, 0x13,
1847 0x00, 0x33,
1848 0xc0, 0x0a,
1849 0xc0, 0x14,
1850 0x00, 0x39,
1851 0x00, 0x2f,
1852 0x00, 0x35,
1853 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001854 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1855 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1856 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1857 };
1858 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1859 sizeof(kTLS11ClientHello))) {
1860 return false;
1861 }
1862
1863 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001864 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1868 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1869 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1870 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1871 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001872 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001873 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001874 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1875 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001876 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1877 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001878 };
1879 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1880 sizeof(kTLS12ClientHello))) {
1881 return false;
1882 }
1883
1884 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1885 // implementation has settled enough that it won't change.
1886
1887 return true;
1888}
1889
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001890static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001891
1892static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1893 // Save the most recent session.
1894 g_last_session.reset(session);
1895 return 1;
1896}
1897
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001898static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001899 SSL_CTX *server_ctx) {
1900 g_last_session = nullptr;
1901 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1902
1903 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001904 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001905 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1906 nullptr /* no session */)) {
1907 fprintf(stderr, "Failed to connect client and server.\n");
1908 return nullptr;
1909 }
1910
1911 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1912 SSL_read(client.get(), nullptr, 0);
1913
1914 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1915
1916 if (!g_last_session) {
1917 fprintf(stderr, "Client did not receive a session.\n");
1918 return nullptr;
1919 }
1920 return std::move(g_last_session);
1921}
1922
1923static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1924 SSL_SESSION *session,
1925 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001926 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001927 if (!ConnectClientAndServer(&client, &server, client_ctx,
1928 server_ctx, session)) {
1929 fprintf(stderr, "Failed to connect client and server.\n");
1930 return false;
1931 }
1932
1933 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1934 fprintf(stderr, "Client and server were inconsistent.\n");
1935 return false;
1936 }
1937
1938 bool was_reused = !!SSL_session_reused(client.get());
1939 if (was_reused != reused) {
1940 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1941 was_reused ? "" : " not");
1942 return false;
1943 }
1944
1945 return true;
1946}
1947
David Benjamin3c51d9b2016-11-01 17:50:42 -04001948static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
1949 SSL_CTX *server_ctx,
1950 SSL_SESSION *session) {
1951 g_last_session = nullptr;
1952 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1953
1954 bssl::UniquePtr<SSL> client, server;
1955 if (!ConnectClientAndServer(&client, &server, client_ctx,
1956 server_ctx, session)) {
1957 fprintf(stderr, "Failed to connect client and server.\n");
1958 return nullptr;
1959 }
1960
1961 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1962 fprintf(stderr, "Client and server were inconsistent.\n");
1963 return nullptr;
1964 }
1965
1966 if (!SSL_session_reused(client.get())) {
1967 fprintf(stderr, "Session was not reused.\n");
1968 return nullptr;
1969 }
1970
1971 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1972 SSL_read(client.get(), nullptr, 0);
1973
1974 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1975
1976 if (!g_last_session) {
1977 fprintf(stderr, "Client did not receive a renewed session.\n");
1978 return nullptr;
1979 }
1980 return std::move(g_last_session);
1981}
1982
David Benjamina933c382016-10-28 00:10:03 -04001983static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
1984 static const uint8_t kContext[] = {3};
1985
1986 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
1987 return SSL_TLSEXT_ERR_ALERT_FATAL;
1988 }
1989
1990 return SSL_TLSEXT_ERR_OK;
1991}
1992
David Benjamin731058e2016-12-03 23:15:13 -05001993static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04001994 static const uint8_t kContext[] = {3};
1995
David Benjamin731058e2016-12-03 23:15:13 -05001996 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
1997 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04001998 return -1;
1999 }
2000
2001 return 1;
2002}
2003
David Benjamin0fef3052016-11-18 15:11:10 +09002004static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2005 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002006 bssl::UniquePtr<X509> cert = GetTestCertificate();
2007 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002008 if (!cert || !key) {
2009 return false;
2010 }
2011
2012 static const uint8_t kContext1[] = {1};
2013 static const uint8_t kContext2[] = {2};
2014
David Benjamin0fef3052016-11-18 15:11:10 +09002015 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2016 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2017 if (!server_ctx || !client_ctx ||
2018 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2019 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2020 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2021 sizeof(kContext1)) ||
2022 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2023 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2024 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2025 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2026 return false;
2027 }
David Benjamina20e5352016-08-02 19:09:41 -04002028
David Benjamin0fef3052016-11-18 15:11:10 +09002029 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2030 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002031
David Benjamin0fef3052016-11-18 15:11:10 +09002032 bssl::UniquePtr<SSL_SESSION> session =
2033 CreateClientSession(client_ctx.get(), server_ctx.get());
2034 if (!session) {
2035 fprintf(stderr, "Error getting session.\n");
2036 return false;
2037 }
David Benjamina20e5352016-08-02 19:09:41 -04002038
David Benjamin0fef3052016-11-18 15:11:10 +09002039 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2040 true /* expect session reused */)) {
2041 fprintf(stderr, "Error resuming session.\n");
2042 return false;
2043 }
David Benjamina20e5352016-08-02 19:09:41 -04002044
David Benjamin0fef3052016-11-18 15:11:10 +09002045 // Change the session ID context.
2046 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2047 sizeof(kContext2))) {
2048 return false;
2049 }
David Benjamina20e5352016-08-02 19:09:41 -04002050
David Benjamin0fef3052016-11-18 15:11:10 +09002051 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2052 false /* expect session not reused */)) {
2053 fprintf(stderr, "Error connecting with a different context.\n");
2054 return false;
2055 }
David Benjamina933c382016-10-28 00:10:03 -04002056
David Benjamin0fef3052016-11-18 15:11:10 +09002057 // Change the session ID context back and install an SNI callback to switch
2058 // it.
2059 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2060 sizeof(kContext1))) {
2061 return false;
2062 }
David Benjamina933c382016-10-28 00:10:03 -04002063
David Benjamin0fef3052016-11-18 15:11:10 +09002064 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2065 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002066
David Benjamin0fef3052016-11-18 15:11:10 +09002067 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2068 false /* expect session not reused */)) {
2069 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2070 return false;
2071 }
David Benjamina933c382016-10-28 00:10:03 -04002072
David Benjamin0fef3052016-11-18 15:11:10 +09002073 // Switch the session ID context with the early callback instead.
2074 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2075 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2076 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002077
David Benjamin0fef3052016-11-18 15:11:10 +09002078 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2079 false /* expect session not reused */)) {
2080 fprintf(stderr,
2081 "Error connecting with a context switch on early callback.\n");
2082 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002083 }
2084
2085 return true;
2086}
2087
David Benjamin721e8b72016-08-03 13:13:17 -04002088static timeval g_current_time;
2089
2090static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2091 *out_clock = g_current_time;
2092}
2093
David Benjamin3c51d9b2016-11-01 17:50:42 -04002094static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2095 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2096 int encrypt) {
2097 static const uint8_t kZeros[16] = {0};
2098
2099 if (encrypt) {
2100 memcpy(key_name, kZeros, sizeof(kZeros));
2101 RAND_bytes(iv, 16);
2102 } else if (memcmp(key_name, kZeros, 16) != 0) {
2103 return 0;
2104 }
2105
2106 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2107 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2108 return -1;
2109 }
2110
2111 // Returning two from the callback in decrypt mode renews the
2112 // session in TLS 1.2 and below.
2113 return encrypt ? 1 : 2;
2114}
2115
David Benjamin123db572016-11-03 16:59:25 -04002116static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002117 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2118 return false;
2119 }
2120
David Benjamin123db572016-11-03 16:59:25 -04002121 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2122 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2123 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2124
David Benjamin9b63f292016-11-15 00:44:05 -05002125#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2126 // Fuzzer-mode tickets are unencrypted.
2127 memcpy(plaintext.get(), ciphertext, len);
2128#else
2129 static const uint8_t kZeros[16] = {0};
2130 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002131 bssl::ScopedEVP_CIPHER_CTX ctx;
2132 int len1, len2;
2133 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2134 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2135 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2136 return false;
2137 }
2138
2139 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002140#endif
David Benjamin123db572016-11-03 16:59:25 -04002141
2142 bssl::UniquePtr<SSL_SESSION> server_session(
2143 SSL_SESSION_from_bytes(plaintext.get(), len));
2144 if (!server_session) {
2145 return false;
2146 }
2147
2148 *out = server_session->time;
2149 return true;
2150}
2151
David Benjamin0fef3052016-11-18 15:11:10 +09002152static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2153 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002154 bssl::UniquePtr<X509> cert = GetTestCertificate();
2155 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002156 if (!cert || !key) {
2157 return false;
2158 }
2159
David Benjamin0fef3052016-11-18 15:11:10 +09002160 for (bool server_test : std::vector<bool>{false, true}) {
2161 static const int kStartTime = 1000;
2162 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002163
David Benjamin0fef3052016-11-18 15:11:10 +09002164 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2165 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2166 if (!server_ctx || !client_ctx ||
2167 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2168 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2169 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2170 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2171 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2172 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2173 return false;
2174 }
2175
2176 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2177 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2178
2179 // Both client and server must enforce session timeouts.
2180 if (server_test) {
2181 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2182 } else {
2183 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2184 }
2185
2186 // Configure a ticket callback which renews tickets.
2187 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2188
2189 bssl::UniquePtr<SSL_SESSION> session =
2190 CreateClientSession(client_ctx.get(), server_ctx.get());
2191 if (!session) {
2192 fprintf(stderr, "Error getting session.\n");
2193 return false;
2194 }
2195
2196 // Advance the clock just behind the timeout.
2197 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
2198
2199 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2200 true /* expect session reused */)) {
2201 fprintf(stderr, "Error resuming session.\n");
2202 return false;
2203 }
2204
2205 // Advance the clock one more second.
2206 g_current_time.tv_sec++;
2207
2208 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2209 false /* expect session not reused */)) {
2210 fprintf(stderr, "Error resuming session.\n");
2211 return false;
2212 }
2213
2214 // Rewind the clock to before the session was minted.
2215 g_current_time.tv_sec = kStartTime - 1;
2216
2217 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2218 false /* expect session not reused */)) {
2219 fprintf(stderr, "Error resuming session.\n");
2220 return false;
2221 }
2222
2223 // SSL 3.0 cannot renew sessions.
2224 if (version == SSL3_VERSION) {
2225 continue;
2226 }
2227
2228 // Renew the session 10 seconds before expiration.
2229 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2230 bssl::UniquePtr<SSL_SESSION> new_session =
2231 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2232 if (!new_session) {
2233 fprintf(stderr, "Error renewing session.\n");
2234 return false;
2235 }
2236
2237 // This new session is not the same object as before.
2238 if (session.get() == new_session.get()) {
2239 fprintf(stderr, "New and old sessions alias.\n");
2240 return false;
2241 }
2242
2243 // Check the sessions have timestamps measured from issuance.
2244 long session_time = 0;
2245 if (server_test) {
2246 if (!GetServerTicketTime(&session_time, new_session.get())) {
2247 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002248 return false;
2249 }
David Benjamin0fef3052016-11-18 15:11:10 +09002250 } else {
2251 session_time = new_session->time;
2252 }
David Benjamin721e8b72016-08-03 13:13:17 -04002253
David Benjamin0fef3052016-11-18 15:11:10 +09002254 if (session_time != g_current_time.tv_sec) {
2255 fprintf(stderr, "New session is not measured from issuance.\n");
2256 return false;
2257 }
David Benjamin721e8b72016-08-03 13:13:17 -04002258
David Benjamin0fef3052016-11-18 15:11:10 +09002259 // The new session is usable just before the old expiration.
2260 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2261 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2262 new_session.get(),
2263 true /* expect session reused */)) {
2264 fprintf(stderr, "Error resuming renewed session.\n");
2265 return false;
2266 }
David Benjamin721e8b72016-08-03 13:13:17 -04002267
David Benjamin0fef3052016-11-18 15:11:10 +09002268 // Renewal does not extend the lifetime, so it is not usable beyond the
2269 // old expiration.
2270 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2271 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2272 new_session.get(),
2273 false /* expect session not reused */)) {
2274 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2275 return false;
David Benjamin1b22f852016-10-27 16:36:32 -04002276 }
David Benjamin721e8b72016-08-03 13:13:17 -04002277 }
2278
2279 return true;
2280}
2281
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002282static int SetSessionTimeoutCallback(SSL *ssl, void *arg) {
2283 long timeout = *(long *) arg;
2284 SSL_set_session_timeout(ssl, timeout);
2285 return 1;
2286}
2287
2288static bool TestSessionTimeoutCertCallback(bool is_dtls,
2289 const SSL_METHOD *method,
2290 uint16_t version) {
2291 static const int kStartTime = 1000;
2292 g_current_time.tv_sec = kStartTime;
2293
2294 bssl::UniquePtr<X509> cert = GetTestCertificate();
2295 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2296 if (!cert || !key) {
2297 return false;
2298 }
2299
2300 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2301 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2302 if (!server_ctx || !client_ctx ||
2303 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2304 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2305 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2306 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2307 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2308 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2309 return false;
2310 }
2311
2312 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2313 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2314
2315 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2316
2317 long timeout = 25;
2318 SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
2319
2320 bssl::UniquePtr<SSL_SESSION> session =
2321 CreateClientSession(client_ctx.get(), server_ctx.get());
2322 if (!session) {
2323 fprintf(stderr, "Error getting session.\n");
2324 return false;
2325 }
2326
2327 // Advance the clock just behind the timeout.
2328 g_current_time.tv_sec += timeout - 1;
2329
2330 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2331 true /* expect session reused */)) {
2332 fprintf(stderr, "Error resuming session.\n");
2333 return false;
2334 }
2335
2336 // Advance the clock one more second.
2337 g_current_time.tv_sec++;
2338
2339 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2340 false /* expect session not reused */)) {
2341 fprintf(stderr, "Error resuming session.\n");
2342 return false;
2343 }
2344
2345 // Set session timeout to 0 to disable resumption.
2346 timeout = 0;
2347 g_current_time.tv_sec = kStartTime;
2348
2349 bssl::UniquePtr<SSL_SESSION> not_resumable_session =
2350 CreateClientSession(client_ctx.get(), server_ctx.get());
2351 if (!not_resumable_session) {
2352 fprintf(stderr, "Error getting session.\n");
2353 return false;
2354 }
2355
2356 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2357 not_resumable_session.get(),
2358 false /* expect session not reused */)) {
2359 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2360 return false;
2361 }
2362
2363 // Set both context and connection (via callback) default session timeout.
2364 // The connection one is the one that ends up being used.
2365 timeout = 25;
2366 g_current_time.tv_sec = kStartTime;
2367
2368 SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
2369
2370 bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
2371 CreateClientSession(client_ctx.get(), server_ctx.get());
2372 if (!ctx_and_cb_session) {
2373 fprintf(stderr, "Error getting session.\n");
2374 return false;
2375 }
2376
2377 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2378 ctx_and_cb_session.get(),
2379 true /* expect session reused */)) {
2380 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2381 return false;
2382 }
2383
2384 // Advance the clock just behind the timeout.
2385 g_current_time.tv_sec += timeout - 1;
2386
2387 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2388 ctx_and_cb_session.get(),
2389 true /* expect session reused */)) {
2390 fprintf(stderr, "Error resuming session.\n");
2391 return false;
2392 }
2393
2394 // Advance the clock one more second.
2395 g_current_time.tv_sec++;
2396
2397 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2398 ctx_and_cb_session.get(),
2399 false /* expect session not reused */)) {
2400 fprintf(stderr, "Error resuming session.\n");
2401 return false;
2402 }
2403
2404 return true;
2405}
2406
David Benjamin0fc37ef2016-08-17 15:29:46 -04002407static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2408 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2409 SSL_set_SSL_CTX(ssl, ctx);
2410 return SSL_TLSEXT_ERR_OK;
2411}
2412
David Benjamin0fef3052016-11-18 15:11:10 +09002413static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2414 uint16_t version) {
2415 // SSL 3.0 lacks extensions.
2416 if (version == SSL3_VERSION) {
2417 return true;
2418 }
2419
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002420 bssl::UniquePtr<X509> cert = GetTestCertificate();
2421 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2422 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2423 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002424 if (!cert || !key || !cert2 || !key2) {
2425 return false;
2426 }
2427
David Benjamin0fef3052016-11-18 15:11:10 +09002428 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2429 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002430
David Benjamin0fef3052016-11-18 15:11:10 +09002431 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2432 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2433 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2434 if (!server_ctx || !server_ctx2 || !client_ctx ||
2435 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2436 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2437 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2438 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2439 // Historically signing preferences would be lost in some cases with the
2440 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2441 // this doesn't happen when |version| is TLS 1.2, configure the private
2442 // key to only sign SHA-256.
2443 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2444 1) ||
2445 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2446 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2447 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2448 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2449 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2450 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2451 return false;
2452 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002453
David Benjamin0fef3052016-11-18 15:11:10 +09002454 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2455 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002456
David Benjamin0fef3052016-11-18 15:11:10 +09002457 bssl::UniquePtr<SSL> client, server;
2458 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2459 server_ctx.get(), nullptr)) {
2460 fprintf(stderr, "Handshake failed.\n");
2461 return false;
2462 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002463
David Benjamin0fef3052016-11-18 15:11:10 +09002464 // The client should have received |cert2|.
2465 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2466 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2467 fprintf(stderr, "Incorrect certificate received.\n");
2468 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002469 }
2470
2471 return true;
2472}
2473
David Benjamin731058e2016-12-03 23:15:13 -05002474static int SetMaxVersion(const SSL_CLIENT_HELLO *client_hello) {
2475 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002476 return -1;
2477 }
2478
David Benjamin99620572016-08-30 00:35:36 -04002479 return 1;
2480}
2481
2482// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2483// maximum version.
2484static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002485 bssl::UniquePtr<X509> cert = GetTestCertificate();
2486 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2487 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2488 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002489 if (!cert || !key || !server_ctx || !client_ctx ||
2490 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002491 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002492 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2493 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002494 return false;
2495 }
2496
David Benjamin99620572016-08-30 00:35:36 -04002497 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2498
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002499 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002500 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2501 server_ctx.get(), nullptr)) {
2502 return false;
2503 }
2504
2505 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2506 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2507 return false;
2508 }
2509
2510 return true;
2511}
2512
David Benjamin2dc02042016-09-19 19:57:37 -04002513static bool TestSetVersion() {
2514 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2515 if (!ctx) {
2516 return false;
2517 }
2518
David Benjamine4706902016-09-20 15:12:23 -04002519 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2520 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2521 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2522 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002523 fprintf(stderr, "Could not set valid TLS version.\n");
2524 return false;
2525 }
2526
David Benjamine4706902016-09-20 15:12:23 -04002527 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2528 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2529 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2530 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2531 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2532 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002533 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2534 return false;
2535 }
2536
David Benjamine34bcc92016-09-21 16:53:09 -04002537 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2538 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2539 fprintf(stderr, "Could not set default TLS version.\n");
2540 return false;
2541 }
2542
2543 if (ctx->min_version != SSL3_VERSION ||
2544 ctx->max_version != TLS1_2_VERSION) {
2545 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2546 ctx->min_version, ctx->max_version);
2547 return false;
2548 }
2549
David Benjamin2dc02042016-09-19 19:57:37 -04002550 ctx.reset(SSL_CTX_new(DTLS_method()));
2551 if (!ctx) {
2552 return false;
2553 }
2554
David Benjamine4706902016-09-20 15:12:23 -04002555 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2556 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2557 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2558 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002559 fprintf(stderr, "Could not set valid DTLS version.\n");
2560 return false;
2561 }
2562
David Benjamine4706902016-09-20 15:12:23 -04002563 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2564 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2565 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2566 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2567 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2568 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2569 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2570 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002571 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2572 return false;
2573 }
2574
David Benjamine34bcc92016-09-21 16:53:09 -04002575 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2576 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2577 fprintf(stderr, "Could not set default DTLS version.\n");
2578 return false;
2579 }
2580
2581 if (ctx->min_version != TLS1_1_VERSION ||
2582 ctx->max_version != TLS1_2_VERSION) {
2583 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2584 ctx->min_version, ctx->max_version);
2585 return false;
2586 }
2587
David Benjamin2dc02042016-09-19 19:57:37 -04002588 return true;
2589}
2590
David Benjamin0fef3052016-11-18 15:11:10 +09002591static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2592 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002593 bssl::UniquePtr<X509> cert = GetTestCertificate();
2594 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2595 if (!cert || !key) {
2596 return false;
2597 }
2598
David Benjamin0fef3052016-11-18 15:11:10 +09002599 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2600 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2601 bssl::UniquePtr<SSL> client, server;
2602 if (!server_ctx || !client_ctx ||
2603 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2604 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2605 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2606 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2607 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2608 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2609 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2610 server_ctx.get(), nullptr /* no session */)) {
2611 fprintf(stderr, "Failed to connect.\n");
2612 return false;
2613 }
David Benjamincb18ac22016-09-27 14:09:15 -04002614
David Benjamin0fef3052016-11-18 15:11:10 +09002615 if (SSL_version(client.get()) != version ||
2616 SSL_version(server.get()) != version) {
2617 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2618 SSL_version(client.get()), SSL_version(server.get()), version);
2619 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002620 }
2621
2622 return true;
2623}
2624
David Benjamin9ef31f02016-10-31 18:01:13 -04002625// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2626// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002627static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2628 uint16_t version) {
2629 // SSL 3.0 lacks extensions.
2630 if (version == SSL3_VERSION) {
2631 return true;
2632 }
2633
David Benjamin9ef31f02016-10-31 18:01:13 -04002634 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2635
2636 bssl::UniquePtr<X509> cert = GetTestCertificate();
2637 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2638 if (!cert || !key) {
2639 return false;
2640 }
2641
David Benjamin0fef3052016-11-18 15:11:10 +09002642 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2643 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2644 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2645 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2646 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2647 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2648 0) {
2649 return false;
2650 }
2651
2652 // The ALPN callback does not fail the handshake on error, so have the
2653 // callback write a boolean.
2654 std::pair<uint16_t, bool> callback_state(version, false);
2655 SSL_CTX_set_alpn_select_cb(
2656 ctx.get(),
2657 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2658 unsigned in_len, void *arg) -> int {
2659 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2660 if (SSL_get_pending_cipher(ssl) != nullptr &&
2661 SSL_version(ssl) == state->first) {
2662 state->second = true;
2663 }
2664 return SSL_TLSEXT_ERR_NOACK;
2665 },
2666 &callback_state);
2667
2668 bssl::UniquePtr<SSL> client, server;
2669 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2670 nullptr /* no session */)) {
2671 return false;
2672 }
2673
2674 if (!callback_state.second) {
2675 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2676 return false;
2677 }
2678
2679 return true;
2680}
2681
David Benjaminb79cc842016-12-07 15:57:14 -05002682static bool TestSSLClearSessionResumption(bool is_dtls,
2683 const SSL_METHOD *method,
2684 uint16_t version) {
2685 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2686 // API pattern.
2687 if (version == TLS1_3_VERSION) {
2688 return true;
2689 }
2690
2691 bssl::UniquePtr<X509> cert = GetTestCertificate();
2692 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2693 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2694 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2695 if (!cert || !key || !server_ctx || !client_ctx ||
2696 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2697 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2698 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2699 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2700 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2701 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2702 return false;
2703 }
2704
2705 // Connect a client and a server.
2706 bssl::UniquePtr<SSL> client, server;
2707 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2708 server_ctx.get(), nullptr /* no session */)) {
2709 return false;
2710 }
2711
2712 if (SSL_session_reused(client.get()) ||
2713 SSL_session_reused(server.get())) {
2714 fprintf(stderr, "Session unexpectedly reused.\n");
2715 return false;
2716 }
2717
2718 // Reset everything.
2719 if (!SSL_clear(client.get()) ||
2720 !SSL_clear(server.get())) {
2721 fprintf(stderr, "SSL_clear failed.\n");
2722 return false;
2723 }
2724
2725 // Attempt to connect a second time.
2726 if (!CompleteHandshakes(client.get(), server.get())) {
2727 fprintf(stderr, "Could not reuse SSL objects.\n");
2728 return false;
2729 }
2730
2731 // |SSL_clear| should implicitly offer the previous session to the server.
2732 if (!SSL_session_reused(client.get()) ||
2733 !SSL_session_reused(server.get())) {
2734 fprintf(stderr, "Session was not reused in second try.\n");
2735 return false;
2736 }
2737
2738 return true;
2739}
2740
David Benjamin0fef3052016-11-18 15:11:10 +09002741static bool ForEachVersion(bool (*test_func)(bool is_dtls,
2742 const SSL_METHOD *method,
2743 uint16_t version)) {
2744 static uint16_t kTLSVersions[] = {
2745 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
2746 TLS1_2_VERSION, TLS1_3_VERSION,
2747 };
2748
2749 static uint16_t kDTLSVersions[] = {
2750 DTLS1_VERSION, DTLS1_2_VERSION,
2751 };
2752
David Benjamin9ef31f02016-10-31 18:01:13 -04002753 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09002754 if (!test_func(false, TLS_method(), version)) {
2755 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002756 return false;
2757 }
David Benjamin0fef3052016-11-18 15:11:10 +09002758 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002759
David Benjamin0fef3052016-11-18 15:11:10 +09002760 for (uint16_t version : kDTLSVersions) {
2761 if (!test_func(true, DTLS_method(), version)) {
2762 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002763 return false;
2764 }
2765 }
2766
2767 return true;
2768}
2769
David Benjamin1d128f32015-09-08 17:41:40 -04002770int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002771 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002772
Adam Langley10f97f32016-07-12 08:09:33 -07002773 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002774 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002775 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2776 !TestSSL_SESSIONEncoding(kCustomSession) ||
2777 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2778 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2779 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2780 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002781 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002782 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2783 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2784 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2785 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2786 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2787 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2788 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2789 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2790 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04002791 // Test the padding extension at TLS 1.2.
2792 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
2793 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
2794 // will be no PSK binder after the padding extension.
2795 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
2796 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
2797 // will be a PSK binder after the padding extension.
2798 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07002799 !TestClientCAList() ||
2800 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002801 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09002802 !ForEachVersion(TestOneSidedShutdown) ||
Steven Valdez87eab492016-06-27 16:34:59 -04002803 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002804 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002805 !TestSetBIO() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002806 !ForEachVersion(TestGetPeerCertificate) ||
2807 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04002808 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002809 !ForEachVersion(TestSessionIDContext) ||
2810 !ForEachVersion(TestSessionTimeout) ||
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002811 !ForEachVersion(TestSessionTimeoutCertCallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002812 !ForEachVersion(TestSNICallback) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002813 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002814 !TestSetVersion() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002815 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05002816 !ForEachVersion(TestALPNCipherAvailable) ||
2817 !ForEachVersion(TestSSLClearSessionResumption)) {
Brian Smith83a82982015-04-09 16:21:10 -10002818 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002819 return 1;
2820 }
2821
David Benjamin2e521212014-07-16 14:37:51 -04002822 printf("PASS\n");
2823 return 0;
2824}