blob: 796c051de27920154a09c60c1ff6a210749cb36b [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 Benjamin17cf2cb2016-12-13 01:07:13 -0500676 OPENSSL_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 Benjamin17cf2cb2016-12-13 01:07:13 -0500714 if (OPENSSL_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 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500841 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400842 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;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001033 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1034 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001035 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
David Benjamin17cf2cb2016-12-13 01:07:13 -05001445 return s0_len == s1_len && OPENSSL_memcmp(s0_bytes, s1_bytes, s0_len) == 0;
Steven Valdez87eab492016-06-27 16:34:59 -04001446}
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 Benjamin17cf2cb2016-12-13 01:07:13 -05001714 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1715 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001716 fprintf(stderr, "peer_sha256 did not match.\n");
1717 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001718 }
1719
1720 return true;
1721}
1722
David Benjaminafc64de2016-07-19 17:12:41 +02001723static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1724 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001725 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001726 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001727 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001728 // Our default cipher list varies by CPU capabilities, so manually place
1729 // the ChaCha20 ciphers in front.
1730 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001731 return false;
1732 }
David Benjamin2dc02042016-09-19 19:57:37 -04001733
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001734 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001735 if (!ssl) {
1736 return false;
1737 }
1738 std::vector<uint8_t> client_hello;
1739 if (!GetClientHello(ssl.get(), &client_hello)) {
1740 return false;
1741 }
1742
1743 // Zero the client_random.
1744 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1745 1 + 3 + // handshake message header
1746 2; // client_version
1747 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1748 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1749 return false;
1750 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001751 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001752
1753 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001754 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001755 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1756 fprintf(stderr, "Got:\n\t");
1757 for (size_t i = 0; i < client_hello.size(); i++) {
1758 fprintf(stderr, "0x%02x, ", client_hello[i]);
1759 }
1760 fprintf(stderr, "\nWanted:\n\t");
1761 for (size_t i = 0; i < expected_len; i++) {
1762 fprintf(stderr, "0x%02x, ", expected[i]);
1763 }
1764 fprintf(stderr, "\n");
1765 return false;
1766 }
1767
1768 return true;
1769}
1770
1771// Tests that our ClientHellos do not change unexpectedly.
1772static bool TestClientHello() {
1773 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001774 0x16,
1775 0x03, 0x00,
1776 0x00, 0x3f,
1777 0x01,
1778 0x00, 0x00, 0x3b,
1779 0x03, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00,
1785 0x00, 0x14,
1786 0xc0, 0x09,
1787 0xc0, 0x13,
1788 0x00, 0x33,
1789 0xc0, 0x0a,
1790 0xc0, 0x14,
1791 0x00, 0x39,
1792 0x00, 0x2f,
1793 0x00, 0x35,
1794 0x00, 0x0a,
1795 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001796 };
1797 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1798 sizeof(kSSL3ClientHello))) {
1799 return false;
1800 }
1801
1802 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001803 0x16,
1804 0x03, 0x01,
1805 0x00, 0x5e,
1806 0x01,
1807 0x00, 0x00, 0x5a,
1808 0x03, 0x01,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00,
1814 0x00, 0x12,
1815 0xc0, 0x09,
1816 0xc0, 0x13,
1817 0x00, 0x33,
1818 0xc0, 0x0a,
1819 0xc0, 0x14,
1820 0x00, 0x39,
1821 0x00, 0x2f,
1822 0x00, 0x35,
1823 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001824 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1825 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1826 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1827 };
1828 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1829 sizeof(kTLS1ClientHello))) {
1830 return false;
1831 }
1832
1833 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001834 0x16,
1835 0x03, 0x01,
1836 0x00, 0x5e,
1837 0x01,
1838 0x00, 0x00, 0x5a,
1839 0x03, 0x02,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00,
1845 0x00, 0x12,
1846 0xc0, 0x09,
1847 0xc0, 0x13,
1848 0x00, 0x33,
1849 0xc0, 0x0a,
1850 0xc0, 0x14,
1851 0x00, 0x39,
1852 0x00, 0x2f,
1853 0x00, 0x35,
1854 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001855 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1856 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1857 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1858 };
1859 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1860 sizeof(kTLS11ClientHello))) {
1861 return false;
1862 }
1863
1864 static const uint8_t kTLS12ClientHello[] = {
David Benjamin3ef76972016-10-17 17:59:54 -04001865 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1869 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1870 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1871 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1872 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
David Benjamin3ef76972016-10-17 17:59:54 -04001873 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
David Benjamin57e929f2016-08-30 00:30:38 -04001874 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjamin3a322f52016-10-26 12:45:35 -04001875 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
1876 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
David Benjamin3ef76972016-10-17 17:59:54 -04001877 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
1878 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001879 };
1880 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1881 sizeof(kTLS12ClientHello))) {
1882 return false;
1883 }
1884
1885 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1886 // implementation has settled enough that it won't change.
1887
1888 return true;
1889}
1890
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001891static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001892
1893static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1894 // Save the most recent session.
1895 g_last_session.reset(session);
1896 return 1;
1897}
1898
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001899static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001900 SSL_CTX *server_ctx) {
1901 g_last_session = nullptr;
1902 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1903
1904 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001905 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001906 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1907 nullptr /* no session */)) {
1908 fprintf(stderr, "Failed to connect client and server.\n");
1909 return nullptr;
1910 }
1911
1912 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1913 SSL_read(client.get(), nullptr, 0);
1914
1915 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1916
1917 if (!g_last_session) {
1918 fprintf(stderr, "Client did not receive a session.\n");
1919 return nullptr;
1920 }
1921 return std::move(g_last_session);
1922}
1923
1924static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1925 SSL_SESSION *session,
1926 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001927 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001928 if (!ConnectClientAndServer(&client, &server, client_ctx,
1929 server_ctx, session)) {
1930 fprintf(stderr, "Failed to connect client and server.\n");
1931 return false;
1932 }
1933
1934 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1935 fprintf(stderr, "Client and server were inconsistent.\n");
1936 return false;
1937 }
1938
1939 bool was_reused = !!SSL_session_reused(client.get());
1940 if (was_reused != reused) {
1941 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1942 was_reused ? "" : " not");
1943 return false;
1944 }
1945
1946 return true;
1947}
1948
David Benjamin3c51d9b2016-11-01 17:50:42 -04001949static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
1950 SSL_CTX *server_ctx,
1951 SSL_SESSION *session) {
1952 g_last_session = nullptr;
1953 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1954
1955 bssl::UniquePtr<SSL> client, server;
1956 if (!ConnectClientAndServer(&client, &server, client_ctx,
1957 server_ctx, session)) {
1958 fprintf(stderr, "Failed to connect client and server.\n");
1959 return nullptr;
1960 }
1961
1962 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1963 fprintf(stderr, "Client and server were inconsistent.\n");
1964 return nullptr;
1965 }
1966
1967 if (!SSL_session_reused(client.get())) {
1968 fprintf(stderr, "Session was not reused.\n");
1969 return nullptr;
1970 }
1971
1972 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1973 SSL_read(client.get(), nullptr, 0);
1974
1975 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1976
1977 if (!g_last_session) {
1978 fprintf(stderr, "Client did not receive a renewed session.\n");
1979 return nullptr;
1980 }
1981 return std::move(g_last_session);
1982}
1983
David Benjamina933c382016-10-28 00:10:03 -04001984static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
1985 static const uint8_t kContext[] = {3};
1986
1987 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
1988 return SSL_TLSEXT_ERR_ALERT_FATAL;
1989 }
1990
1991 return SSL_TLSEXT_ERR_OK;
1992}
1993
David Benjamin731058e2016-12-03 23:15:13 -05001994static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04001995 static const uint8_t kContext[] = {3};
1996
David Benjamin731058e2016-12-03 23:15:13 -05001997 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
1998 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04001999 return -1;
2000 }
2001
2002 return 1;
2003}
2004
David Benjamin0fef3052016-11-18 15:11:10 +09002005static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2006 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002007 bssl::UniquePtr<X509> cert = GetTestCertificate();
2008 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002009 if (!cert || !key) {
2010 return false;
2011 }
2012
2013 static const uint8_t kContext1[] = {1};
2014 static const uint8_t kContext2[] = {2};
2015
David Benjamin0fef3052016-11-18 15:11:10 +09002016 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2017 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2018 if (!server_ctx || !client_ctx ||
2019 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2020 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2021 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2022 sizeof(kContext1)) ||
2023 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2024 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2025 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2026 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2027 return false;
2028 }
David Benjamina20e5352016-08-02 19:09:41 -04002029
David Benjamin0fef3052016-11-18 15:11:10 +09002030 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2031 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002032
David Benjamin0fef3052016-11-18 15:11:10 +09002033 bssl::UniquePtr<SSL_SESSION> session =
2034 CreateClientSession(client_ctx.get(), server_ctx.get());
2035 if (!session) {
2036 fprintf(stderr, "Error getting session.\n");
2037 return false;
2038 }
David Benjamina20e5352016-08-02 19:09:41 -04002039
David Benjamin0fef3052016-11-18 15:11:10 +09002040 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2041 true /* expect session reused */)) {
2042 fprintf(stderr, "Error resuming session.\n");
2043 return false;
2044 }
David Benjamina20e5352016-08-02 19:09:41 -04002045
David Benjamin0fef3052016-11-18 15:11:10 +09002046 // Change the session ID context.
2047 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2048 sizeof(kContext2))) {
2049 return false;
2050 }
David Benjamina20e5352016-08-02 19:09:41 -04002051
David Benjamin0fef3052016-11-18 15:11:10 +09002052 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2053 false /* expect session not reused */)) {
2054 fprintf(stderr, "Error connecting with a different context.\n");
2055 return false;
2056 }
David Benjamina933c382016-10-28 00:10:03 -04002057
David Benjamin0fef3052016-11-18 15:11:10 +09002058 // Change the session ID context back and install an SNI callback to switch
2059 // it.
2060 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2061 sizeof(kContext1))) {
2062 return false;
2063 }
David Benjamina933c382016-10-28 00:10:03 -04002064
David Benjamin0fef3052016-11-18 15:11:10 +09002065 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2066 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002067
David Benjamin0fef3052016-11-18 15:11:10 +09002068 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2069 false /* expect session not reused */)) {
2070 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2071 return false;
2072 }
David Benjamina933c382016-10-28 00:10:03 -04002073
David Benjamin0fef3052016-11-18 15:11:10 +09002074 // Switch the session ID context with the early callback instead.
2075 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2076 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2077 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002078
David Benjamin0fef3052016-11-18 15:11:10 +09002079 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2080 false /* expect session not reused */)) {
2081 fprintf(stderr,
2082 "Error connecting with a context switch on early callback.\n");
2083 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002084 }
2085
2086 return true;
2087}
2088
David Benjamin721e8b72016-08-03 13:13:17 -04002089static timeval g_current_time;
2090
2091static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2092 *out_clock = g_current_time;
2093}
2094
David Benjamin3c51d9b2016-11-01 17:50:42 -04002095static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2096 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2097 int encrypt) {
2098 static const uint8_t kZeros[16] = {0};
2099
2100 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002101 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002102 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002103 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002104 return 0;
2105 }
2106
2107 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2108 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2109 return -1;
2110 }
2111
2112 // Returning two from the callback in decrypt mode renews the
2113 // session in TLS 1.2 and below.
2114 return encrypt ? 1 : 2;
2115}
2116
David Benjamin123db572016-11-03 16:59:25 -04002117static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002118 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2119 return false;
2120 }
2121
David Benjamin123db572016-11-03 16:59:25 -04002122 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2123 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2124 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2125
David Benjamin9b63f292016-11-15 00:44:05 -05002126#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2127 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002128 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002129#else
2130 static const uint8_t kZeros[16] = {0};
2131 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002132 bssl::ScopedEVP_CIPHER_CTX ctx;
2133 int len1, len2;
2134 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2135 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2136 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2137 return false;
2138 }
2139
2140 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002141#endif
David Benjamin123db572016-11-03 16:59:25 -04002142
2143 bssl::UniquePtr<SSL_SESSION> server_session(
2144 SSL_SESSION_from_bytes(plaintext.get(), len));
2145 if (!server_session) {
2146 return false;
2147 }
2148
2149 *out = server_session->time;
2150 return true;
2151}
2152
David Benjamin0fef3052016-11-18 15:11:10 +09002153static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2154 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002155 bssl::UniquePtr<X509> cert = GetTestCertificate();
2156 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002157 if (!cert || !key) {
2158 return false;
2159 }
2160
David Benjamin0fef3052016-11-18 15:11:10 +09002161 for (bool server_test : std::vector<bool>{false, true}) {
2162 static const int kStartTime = 1000;
2163 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002164
David Benjamin0fef3052016-11-18 15:11:10 +09002165 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2166 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2167 if (!server_ctx || !client_ctx ||
2168 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2169 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2170 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2171 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2172 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2173 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2174 return false;
2175 }
2176
2177 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2178 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2179
2180 // Both client and server must enforce session timeouts.
2181 if (server_test) {
2182 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2183 } else {
2184 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2185 }
2186
2187 // Configure a ticket callback which renews tickets.
2188 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2189
2190 bssl::UniquePtr<SSL_SESSION> session =
2191 CreateClientSession(client_ctx.get(), server_ctx.get());
2192 if (!session) {
2193 fprintf(stderr, "Error getting session.\n");
2194 return false;
2195 }
2196
2197 // Advance the clock just behind the timeout.
2198 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
2199
2200 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2201 true /* expect session reused */)) {
2202 fprintf(stderr, "Error resuming session.\n");
2203 return false;
2204 }
2205
2206 // Advance the clock one more second.
2207 g_current_time.tv_sec++;
2208
2209 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2210 false /* expect session not reused */)) {
2211 fprintf(stderr, "Error resuming session.\n");
2212 return false;
2213 }
2214
2215 // Rewind the clock to before the session was minted.
2216 g_current_time.tv_sec = kStartTime - 1;
2217
2218 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2219 false /* expect session not reused */)) {
2220 fprintf(stderr, "Error resuming session.\n");
2221 return false;
2222 }
2223
2224 // SSL 3.0 cannot renew sessions.
2225 if (version == SSL3_VERSION) {
2226 continue;
2227 }
2228
2229 // Renew the session 10 seconds before expiration.
2230 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2231 bssl::UniquePtr<SSL_SESSION> new_session =
2232 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2233 if (!new_session) {
2234 fprintf(stderr, "Error renewing session.\n");
2235 return false;
2236 }
2237
2238 // This new session is not the same object as before.
2239 if (session.get() == new_session.get()) {
2240 fprintf(stderr, "New and old sessions alias.\n");
2241 return false;
2242 }
2243
2244 // Check the sessions have timestamps measured from issuance.
2245 long session_time = 0;
2246 if (server_test) {
2247 if (!GetServerTicketTime(&session_time, new_session.get())) {
2248 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002249 return false;
2250 }
David Benjamin0fef3052016-11-18 15:11:10 +09002251 } else {
2252 session_time = new_session->time;
2253 }
David Benjamin721e8b72016-08-03 13:13:17 -04002254
David Benjamin0fef3052016-11-18 15:11:10 +09002255 if (session_time != g_current_time.tv_sec) {
2256 fprintf(stderr, "New session is not measured from issuance.\n");
2257 return false;
2258 }
David Benjamin721e8b72016-08-03 13:13:17 -04002259
David Benjamin0fef3052016-11-18 15:11:10 +09002260 // The new session is usable just before the old expiration.
2261 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2262 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2263 new_session.get(),
2264 true /* expect session reused */)) {
2265 fprintf(stderr, "Error resuming renewed session.\n");
2266 return false;
2267 }
David Benjamin721e8b72016-08-03 13:13:17 -04002268
David Benjamin0fef3052016-11-18 15:11:10 +09002269 // Renewal does not extend the lifetime, so it is not usable beyond the
2270 // old expiration.
2271 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2272 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2273 new_session.get(),
2274 false /* expect session not reused */)) {
2275 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2276 return false;
David Benjamin1b22f852016-10-27 16:36:32 -04002277 }
David Benjamin721e8b72016-08-03 13:13:17 -04002278 }
2279
2280 return true;
2281}
2282
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002283static int SetSessionTimeoutCallback(SSL *ssl, void *arg) {
2284 long timeout = *(long *) arg;
2285 SSL_set_session_timeout(ssl, timeout);
2286 return 1;
2287}
2288
2289static bool TestSessionTimeoutCertCallback(bool is_dtls,
2290 const SSL_METHOD *method,
2291 uint16_t version) {
2292 static const int kStartTime = 1000;
2293 g_current_time.tv_sec = kStartTime;
2294
2295 bssl::UniquePtr<X509> cert = GetTestCertificate();
2296 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2297 if (!cert || !key) {
2298 return false;
2299 }
2300
2301 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2302 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2303 if (!server_ctx || !client_ctx ||
2304 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2305 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2306 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2307 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2308 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2309 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2310 return false;
2311 }
2312
2313 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2314 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2315
2316 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2317
2318 long timeout = 25;
2319 SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
2320
2321 bssl::UniquePtr<SSL_SESSION> session =
2322 CreateClientSession(client_ctx.get(), server_ctx.get());
2323 if (!session) {
2324 fprintf(stderr, "Error getting session.\n");
2325 return false;
2326 }
2327
2328 // Advance the clock just behind the timeout.
2329 g_current_time.tv_sec += timeout - 1;
2330
2331 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2332 true /* expect session reused */)) {
2333 fprintf(stderr, "Error resuming session.\n");
2334 return false;
2335 }
2336
2337 // Advance the clock one more second.
2338 g_current_time.tv_sec++;
2339
2340 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2341 false /* expect session not reused */)) {
2342 fprintf(stderr, "Error resuming session.\n");
2343 return false;
2344 }
2345
2346 // Set session timeout to 0 to disable resumption.
2347 timeout = 0;
2348 g_current_time.tv_sec = kStartTime;
2349
2350 bssl::UniquePtr<SSL_SESSION> not_resumable_session =
2351 CreateClientSession(client_ctx.get(), server_ctx.get());
2352 if (!not_resumable_session) {
2353 fprintf(stderr, "Error getting session.\n");
2354 return false;
2355 }
2356
2357 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2358 not_resumable_session.get(),
2359 false /* expect session not reused */)) {
2360 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2361 return false;
2362 }
2363
2364 // Set both context and connection (via callback) default session timeout.
2365 // The connection one is the one that ends up being used.
2366 timeout = 25;
2367 g_current_time.tv_sec = kStartTime;
2368
2369 SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
2370
2371 bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
2372 CreateClientSession(client_ctx.get(), server_ctx.get());
2373 if (!ctx_and_cb_session) {
2374 fprintf(stderr, "Error getting session.\n");
2375 return false;
2376 }
2377
2378 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2379 ctx_and_cb_session.get(),
2380 true /* expect session reused */)) {
2381 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2382 return false;
2383 }
2384
2385 // Advance the clock just behind the timeout.
2386 g_current_time.tv_sec += timeout - 1;
2387
2388 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2389 ctx_and_cb_session.get(),
2390 true /* expect session reused */)) {
2391 fprintf(stderr, "Error resuming session.\n");
2392 return false;
2393 }
2394
2395 // Advance the clock one more second.
2396 g_current_time.tv_sec++;
2397
2398 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2399 ctx_and_cb_session.get(),
2400 false /* expect session not reused */)) {
2401 fprintf(stderr, "Error resuming session.\n");
2402 return false;
2403 }
2404
2405 return true;
2406}
2407
David Benjamin0fc37ef2016-08-17 15:29:46 -04002408static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2409 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2410 SSL_set_SSL_CTX(ssl, ctx);
2411 return SSL_TLSEXT_ERR_OK;
2412}
2413
David Benjamin0fef3052016-11-18 15:11:10 +09002414static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2415 uint16_t version) {
2416 // SSL 3.0 lacks extensions.
2417 if (version == SSL3_VERSION) {
2418 return true;
2419 }
2420
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002421 bssl::UniquePtr<X509> cert = GetTestCertificate();
2422 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2423 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2424 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002425 if (!cert || !key || !cert2 || !key2) {
2426 return false;
2427 }
2428
David Benjamin0fef3052016-11-18 15:11:10 +09002429 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2430 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002431
David Benjamin0fef3052016-11-18 15:11:10 +09002432 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2433 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2434 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2435 if (!server_ctx || !server_ctx2 || !client_ctx ||
2436 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2437 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2438 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2439 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2440 // Historically signing preferences would be lost in some cases with the
2441 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2442 // this doesn't happen when |version| is TLS 1.2, configure the private
2443 // key to only sign SHA-256.
2444 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2445 1) ||
2446 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2447 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2448 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2449 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2450 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2451 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2452 return false;
2453 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002454
David Benjamin0fef3052016-11-18 15:11:10 +09002455 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2456 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002457
David Benjamin0fef3052016-11-18 15:11:10 +09002458 bssl::UniquePtr<SSL> client, server;
2459 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2460 server_ctx.get(), nullptr)) {
2461 fprintf(stderr, "Handshake failed.\n");
2462 return false;
2463 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002464
David Benjamin0fef3052016-11-18 15:11:10 +09002465 // The client should have received |cert2|.
2466 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2467 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2468 fprintf(stderr, "Incorrect certificate received.\n");
2469 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002470 }
2471
2472 return true;
2473}
2474
David Benjamin731058e2016-12-03 23:15:13 -05002475static int SetMaxVersion(const SSL_CLIENT_HELLO *client_hello) {
2476 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002477 return -1;
2478 }
2479
David Benjamin99620572016-08-30 00:35:36 -04002480 return 1;
2481}
2482
2483// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2484// maximum version.
2485static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002486 bssl::UniquePtr<X509> cert = GetTestCertificate();
2487 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2488 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2489 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002490 if (!cert || !key || !server_ctx || !client_ctx ||
2491 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002492 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002493 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2494 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002495 return false;
2496 }
2497
David Benjamin99620572016-08-30 00:35:36 -04002498 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2499
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002500 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002501 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2502 server_ctx.get(), nullptr)) {
2503 return false;
2504 }
2505
2506 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2507 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2508 return false;
2509 }
2510
2511 return true;
2512}
2513
David Benjamin2dc02042016-09-19 19:57:37 -04002514static bool TestSetVersion() {
2515 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2516 if (!ctx) {
2517 return false;
2518 }
2519
David Benjamine4706902016-09-20 15:12:23 -04002520 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2521 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2522 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2523 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002524 fprintf(stderr, "Could not set valid TLS version.\n");
2525 return false;
2526 }
2527
David Benjamine4706902016-09-20 15:12:23 -04002528 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2529 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2530 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2531 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2532 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2533 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002534 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2535 return false;
2536 }
2537
David Benjamine34bcc92016-09-21 16:53:09 -04002538 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2539 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2540 fprintf(stderr, "Could not set default TLS version.\n");
2541 return false;
2542 }
2543
2544 if (ctx->min_version != SSL3_VERSION ||
2545 ctx->max_version != TLS1_2_VERSION) {
2546 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2547 ctx->min_version, ctx->max_version);
2548 return false;
2549 }
2550
David Benjamin2dc02042016-09-19 19:57:37 -04002551 ctx.reset(SSL_CTX_new(DTLS_method()));
2552 if (!ctx) {
2553 return false;
2554 }
2555
David Benjamine4706902016-09-20 15:12:23 -04002556 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2557 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2558 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2559 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002560 fprintf(stderr, "Could not set valid DTLS version.\n");
2561 return false;
2562 }
2563
David Benjamine4706902016-09-20 15:12:23 -04002564 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2565 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2566 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2567 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2568 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2569 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2570 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2571 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002572 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2573 return false;
2574 }
2575
David Benjamine34bcc92016-09-21 16:53:09 -04002576 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2577 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2578 fprintf(stderr, "Could not set default DTLS version.\n");
2579 return false;
2580 }
2581
2582 if (ctx->min_version != TLS1_1_VERSION ||
2583 ctx->max_version != TLS1_2_VERSION) {
2584 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2585 ctx->min_version, ctx->max_version);
2586 return false;
2587 }
2588
David Benjamin2dc02042016-09-19 19:57:37 -04002589 return true;
2590}
2591
David Benjamin458334a2016-12-15 13:53:25 -05002592static const char *GetVersionName(uint16_t version) {
2593 switch (version) {
2594 case SSL3_VERSION:
2595 return "SSLv3";
2596 case TLS1_VERSION:
2597 return "TLSv1";
2598 case TLS1_1_VERSION:
2599 return "TLSv1.1";
2600 case TLS1_2_VERSION:
2601 return "TLSv1.2";
2602 case TLS1_3_VERSION:
2603 return "TLSv1.3";
2604 case DTLS1_VERSION:
2605 return "DTLSv1";
2606 case DTLS1_2_VERSION:
2607 return "DTLSv1.2";
2608 default:
2609 return "???";
2610 }
2611}
2612
David Benjamin0fef3052016-11-18 15:11:10 +09002613static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2614 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002615 bssl::UniquePtr<X509> cert = GetTestCertificate();
2616 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2617 if (!cert || !key) {
2618 return false;
2619 }
2620
David Benjamin0fef3052016-11-18 15:11:10 +09002621 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2622 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2623 bssl::UniquePtr<SSL> client, server;
2624 if (!server_ctx || !client_ctx ||
2625 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2626 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2627 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2628 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2629 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2630 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2631 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2632 server_ctx.get(), nullptr /* no session */)) {
2633 fprintf(stderr, "Failed to connect.\n");
2634 return false;
2635 }
David Benjamincb18ac22016-09-27 14:09:15 -04002636
David Benjamin0fef3052016-11-18 15:11:10 +09002637 if (SSL_version(client.get()) != version ||
2638 SSL_version(server.get()) != version) {
2639 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2640 SSL_version(client.get()), SSL_version(server.get()), version);
2641 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002642 }
2643
David Benjamin458334a2016-12-15 13:53:25 -05002644 // Test the version name is reported as expected.
2645 const char *version_name = GetVersionName(version);
2646 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2647 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2648 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2649 SSL_get_version(client.get()), SSL_get_version(server.get()),
2650 version_name);
2651 return false;
2652 }
2653
2654 // Test SSL_SESSION reports the same name.
2655 const char *client_name =
2656 SSL_SESSION_get_version(SSL_get_session(client.get()));
2657 const char *server_name =
2658 SSL_SESSION_get_version(SSL_get_session(server.get()));
2659 if (strcmp(version_name, client_name) != 0 ||
2660 strcmp(version_name, server_name) != 0) {
2661 fprintf(stderr,
2662 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2663 client_name, server_name, version_name);
2664 return false;
2665 }
2666
David Benjamincb18ac22016-09-27 14:09:15 -04002667 return true;
2668}
2669
David Benjamin9ef31f02016-10-31 18:01:13 -04002670// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2671// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002672static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2673 uint16_t version) {
2674 // SSL 3.0 lacks extensions.
2675 if (version == SSL3_VERSION) {
2676 return true;
2677 }
2678
David Benjamin9ef31f02016-10-31 18:01:13 -04002679 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2680
2681 bssl::UniquePtr<X509> cert = GetTestCertificate();
2682 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2683 if (!cert || !key) {
2684 return false;
2685 }
2686
David Benjamin0fef3052016-11-18 15:11:10 +09002687 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2688 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2689 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2690 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2691 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2692 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2693 0) {
2694 return false;
2695 }
2696
2697 // The ALPN callback does not fail the handshake on error, so have the
2698 // callback write a boolean.
2699 std::pair<uint16_t, bool> callback_state(version, false);
2700 SSL_CTX_set_alpn_select_cb(
2701 ctx.get(),
2702 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2703 unsigned in_len, void *arg) -> int {
2704 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2705 if (SSL_get_pending_cipher(ssl) != nullptr &&
2706 SSL_version(ssl) == state->first) {
2707 state->second = true;
2708 }
2709 return SSL_TLSEXT_ERR_NOACK;
2710 },
2711 &callback_state);
2712
2713 bssl::UniquePtr<SSL> client, server;
2714 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2715 nullptr /* no session */)) {
2716 return false;
2717 }
2718
2719 if (!callback_state.second) {
2720 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2721 return false;
2722 }
2723
2724 return true;
2725}
2726
David Benjaminb79cc842016-12-07 15:57:14 -05002727static bool TestSSLClearSessionResumption(bool is_dtls,
2728 const SSL_METHOD *method,
2729 uint16_t version) {
2730 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2731 // API pattern.
2732 if (version == TLS1_3_VERSION) {
2733 return true;
2734 }
2735
2736 bssl::UniquePtr<X509> cert = GetTestCertificate();
2737 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2738 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2739 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2740 if (!cert || !key || !server_ctx || !client_ctx ||
2741 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2742 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2743 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2744 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2745 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2746 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2747 return false;
2748 }
2749
2750 // Connect a client and a server.
2751 bssl::UniquePtr<SSL> client, server;
2752 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2753 server_ctx.get(), nullptr /* no session */)) {
2754 return false;
2755 }
2756
2757 if (SSL_session_reused(client.get()) ||
2758 SSL_session_reused(server.get())) {
2759 fprintf(stderr, "Session unexpectedly reused.\n");
2760 return false;
2761 }
2762
2763 // Reset everything.
2764 if (!SSL_clear(client.get()) ||
2765 !SSL_clear(server.get())) {
2766 fprintf(stderr, "SSL_clear failed.\n");
2767 return false;
2768 }
2769
2770 // Attempt to connect a second time.
2771 if (!CompleteHandshakes(client.get(), server.get())) {
2772 fprintf(stderr, "Could not reuse SSL objects.\n");
2773 return false;
2774 }
2775
2776 // |SSL_clear| should implicitly offer the previous session to the server.
2777 if (!SSL_session_reused(client.get()) ||
2778 !SSL_session_reused(server.get())) {
2779 fprintf(stderr, "Session was not reused in second try.\n");
2780 return false;
2781 }
2782
2783 return true;
2784}
2785
David Benjamin0fef3052016-11-18 15:11:10 +09002786static bool ForEachVersion(bool (*test_func)(bool is_dtls,
2787 const SSL_METHOD *method,
2788 uint16_t version)) {
2789 static uint16_t kTLSVersions[] = {
2790 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
2791 TLS1_2_VERSION, TLS1_3_VERSION,
2792 };
2793
2794 static uint16_t kDTLSVersions[] = {
2795 DTLS1_VERSION, DTLS1_2_VERSION,
2796 };
2797
David Benjamin9ef31f02016-10-31 18:01:13 -04002798 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09002799 if (!test_func(false, TLS_method(), version)) {
2800 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002801 return false;
2802 }
David Benjamin0fef3052016-11-18 15:11:10 +09002803 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002804
David Benjamin0fef3052016-11-18 15:11:10 +09002805 for (uint16_t version : kDTLSVersions) {
2806 if (!test_func(true, DTLS_method(), version)) {
2807 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04002808 return false;
2809 }
2810 }
2811
2812 return true;
2813}
2814
David Benjamin1d128f32015-09-08 17:41:40 -04002815int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002816 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002817
Adam Langley10f97f32016-07-12 08:09:33 -07002818 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002819 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002820 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2821 !TestSSL_SESSIONEncoding(kCustomSession) ||
2822 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2823 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2824 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2825 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002826 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002827 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2828 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2829 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2830 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2831 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2832 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2833 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2834 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2835 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04002836 // Test the padding extension at TLS 1.2.
2837 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
2838 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
2839 // will be no PSK binder after the padding extension.
2840 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
2841 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
2842 // will be a PSK binder after the padding extension.
2843 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07002844 !TestClientCAList() ||
2845 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002846 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09002847 !ForEachVersion(TestOneSidedShutdown) ||
Steven Valdez87eab492016-06-27 16:34:59 -04002848 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002849 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002850 !TestSetBIO() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002851 !ForEachVersion(TestGetPeerCertificate) ||
2852 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04002853 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002854 !ForEachVersion(TestSessionIDContext) ||
2855 !ForEachVersion(TestSessionTimeout) ||
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002856 !ForEachVersion(TestSessionTimeoutCertCallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002857 !ForEachVersion(TestSNICallback) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002858 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002859 !TestSetVersion() ||
David Benjamin0fef3052016-11-18 15:11:10 +09002860 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05002861 !ForEachVersion(TestALPNCipherAvailable) ||
2862 !ForEachVersion(TestSSLClearSessionResumption)) {
Brian Smith83a82982015-04-09 16:21:10 -10002863 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002864 return 1;
2865 }
2866
David Benjamin2e521212014-07-16 14:37:51 -04002867 printf("PASS\n");
2868 return 0;
2869}