blob: b27673b9aa1a922367740ceab76f5a16ced6fd69 [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},
David Benjaminfb974e62015-12-16 19:34:22 -050078 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050079 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
80 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
81 },
82 },
83 // + reorders selected ciphers to the end, keeping their relative order.
84 {
85 "ECDHE-ECDSA-CHACHA20-POLY1305:"
86 "ECDHE-RSA-CHACHA20-POLY1305:"
87 "ECDHE-ECDSA-AES128-GCM-SHA256:"
88 "ECDHE-RSA-AES128-GCM-SHA256:"
89 "+aRSA",
90 {
91 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050092 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050094 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
95 },
96 },
97 // ! banishes ciphers from future selections.
98 {
99 "!aRSA:"
100 "ECDHE-ECDSA-CHACHA20-POLY1305:"
101 "ECDHE-RSA-CHACHA20-POLY1305:"
102 "ECDHE-ECDSA-AES128-GCM-SHA256:"
103 "ECDHE-RSA-AES128-GCM-SHA256",
104 {
105 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500106 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
107 },
108 },
109 // Multiple masks can be ANDed in a single rule.
110 {
111 "kRSA+AESGCM+AES128",
112 {
113 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
114 },
115 },
116 // - removes selected ciphers, but preserves their order for future
117 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
118 // ECDHE_RSA.
119 {
120 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
121 "AESGCM+AES128+aRSA",
122 {
123 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
124 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
125 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
126 },
127 },
128 // Unknown selectors are no-ops.
129 {
130 "ECDHE-ECDSA-CHACHA20-POLY1305:"
131 "ECDHE-RSA-CHACHA20-POLY1305:"
132 "ECDHE-ECDSA-AES128-GCM-SHA256:"
133 "ECDHE-RSA-AES128-GCM-SHA256:"
134 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
135 {
136 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500137 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500138 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
139 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
140 },
141 },
142 // Square brackets specify equi-preference groups.
143 {
144 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
145 "[ECDHE-RSA-CHACHA20-POLY1305]:"
146 "ECDHE-RSA-AES128-GCM-SHA256",
147 {
148 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500149 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800150 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500151 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
152 },
153 },
154 // @STRENGTH performs a stable strength-sort of the selected ciphers and
155 // only the selected ciphers.
156 {
157 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700158 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500159 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
160 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700161 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500162 // Select ECDHE ones and sort them by strength. Ties should resolve
163 // based on the order above.
164 "kECDHE:@STRENGTH:-ALL:"
165 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
166 // by strength. Then RSA, backwards by strength.
167 "aRSA",
168 {
169 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
170 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500171 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500172 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
173 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
174 },
175 },
176 // Exact ciphers may not be used in multi-part rules; they are treated
177 // as unknown aliases.
178 {
179 "ECDHE-ECDSA-AES128-GCM-SHA256:"
180 "ECDHE-RSA-AES128-GCM-SHA256:"
181 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
182 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
183 {
184 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
185 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
186 },
187 },
188 // SSLv3 matches everything that existed before TLS 1.2.
189 {
190 "AES128-SHA:AES128-SHA256:!SSLv3",
191 {
192 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
193 },
194 },
195 // TLSv1.2 matches everything added in TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!TLSv1.2",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
200 },
201 },
202 // The two directives have no intersection.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
208 },
209 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400210};
211
212static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400213 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400214 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
215 "RSA]",
216 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400217 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400218 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400219 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400220 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400221 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400222 "",
223 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400224 // COMPLEMENTOFDEFAULT is empty.
225 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400226 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400227 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400228 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400229 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
230 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
231 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
232 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700233 // Opcode supplied, but missing selector.
234 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235};
236
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700237static const char *kMustNotIncludeNull[] = {
238 "ALL",
239 "DEFAULT",
240 "ALL:!eNULL",
241 "ALL:!NULL",
David Benjamind6e9eec2015-11-18 09:48:55 -0500242 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700243 "FIPS",
244 "SHA",
245 "SHA1",
246 "RSA",
247 "SSLv3",
248 "TLSv1",
249 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700250};
251
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100252static const CurveTest kCurveTests[] = {
253 {
254 "P-256",
255 { SSL_CURVE_SECP256R1 },
256 },
257 {
258 "P-256:P-384:P-521:X25519",
259 {
260 SSL_CURVE_SECP256R1,
261 SSL_CURVE_SECP384R1,
262 SSL_CURVE_SECP521R1,
263 SSL_CURVE_X25519,
264 },
265 },
266};
267
268static const char *kBadCurvesLists[] = {
269 "",
270 ":",
271 "::",
272 "P-256::X25519",
273 "RSA:P-256",
274 "P-256:RSA",
275 "X25519:P-256:",
276 ":X25519:P-256",
277};
278
David Benjamin1d77e562015-03-22 17:22:08 -0400279static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
280 bool in_group = false;
281 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400282 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
283 if (!in_group && list->in_group_flags[i]) {
284 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400285 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400286 }
287 fprintf(stderr, "\t");
288 if (in_group) {
289 fprintf(stderr, " ");
290 }
291 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
292 if (in_group && !list->in_group_flags[i]) {
293 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400294 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400295 }
296 }
297}
298
David Benjaminfb974e62015-12-16 19:34:22 -0500299static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700300 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400301 if (!ctx) {
302 return false;
David Benjamin65226252015-02-05 16:49:47 -0500303 }
304
David Benjaminfb974e62015-12-16 19:34:22 -0500305 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
306 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400307 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400308 }
309
David Benjamin1d77e562015-03-22 17:22:08 -0400310 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500311 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
312 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
313 PrintCipherPreferenceList(ctx->cipher_list);
314 return false;
315 }
316
317 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400318 const SSL_CIPHER *cipher =
319 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500320 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
321 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
322 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400323 PrintCipherPreferenceList(ctx->cipher_list);
324 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400325 }
326 }
327
David Benjamin1d77e562015-03-22 17:22:08 -0400328 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400329}
330
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700331static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700332 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700333 if (!ctx) {
334 return false;
335 }
336 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
337 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
338 return false;
339 }
340 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
341 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
342 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
343 return false;
344 }
345 }
346 return true;
347}
348
David Benjamin1d77e562015-03-22 17:22:08 -0400349static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500350 for (const CipherTest &test : kCipherTests) {
351 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400352 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400353 }
354 }
355
David Benjaminfb974e62015-12-16 19:34:22 -0500356 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700357 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400358 if (!ctx) {
359 return false;
David Benjamin65226252015-02-05 16:49:47 -0500360 }
David Benjaminfb974e62015-12-16 19:34:22 -0500361 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
362 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400363 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 }
365 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400366 }
367
David Benjaminfb974e62015-12-16 19:34:22 -0500368 for (const char *rule : kMustNotIncludeNull) {
369 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700370 return false;
371 }
372 }
373
David Benjamin1d77e562015-03-22 17:22:08 -0400374 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400375}
David Benjamin2e521212014-07-16 14:37:51 -0400376
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100377static bool TestCurveRule(const CurveTest &t) {
378 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
379 if (!ctx) {
380 return false;
381 }
382
383 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
384 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
385 return false;
386 }
387
388 // Compare the two lists.
389 if (ctx->supported_group_list_len != t.expected.size()) {
390 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
391 return false;
392 }
393
394 for (size_t i = 0; i < t.expected.size(); i++) {
395 if (t.expected[i] != ctx->supported_group_list[i]) {
396 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
397 return false;
398 }
399 }
400
401 return true;
402}
403
404static bool TestCurveRules() {
405 for (const CurveTest &test : kCurveTests) {
406 if (!TestCurveRule(test)) {
407 return false;
408 }
409 }
410
411 for (const char *rule : kBadCurvesLists) {
412 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
413 if (!ctx) {
414 return false;
415 }
416 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
417 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
418 return false;
419 }
420 ERR_clear_error();
421 }
422
423 return true;
424}
425
Adam Langley364f7a62016-12-12 10:51:00 -0800426// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700427static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800428 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700429 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
430 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
431 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
432 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
433 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
434 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
435 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
436 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
437 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
438 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
439 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
440 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
441 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
442 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
443 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
444 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
445 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
446 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
447 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
448 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
449 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
450 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
451 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
452 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
453 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
454 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
455 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
456 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
457 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800458 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700459
460// kCustomSession is a custom serialized SSL_SESSION generated by
461// filling in missing fields from |kOpenSSLSession|. This includes
462// providing |peer_sha256|, so |peer| is not serialized.
463static const char kCustomSession[] =
464 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
465 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
466 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
467 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
468 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
469 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
470 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
471 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
472
473// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
474static const char kBoringSSLSession[] =
475 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
476 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
477 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
478 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
479 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
480 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
481 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
482 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
483 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
484 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
485 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
486 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
487 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
488 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
489 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
490 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
491 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
492 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
493 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
494 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
495 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
496 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
497 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
498 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
499 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
500 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
501 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
502 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
503 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
504 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
505 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
506 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
507 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
508 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
509 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
510 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
511 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
512 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
513 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
514 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
515 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
516 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
517 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
518 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
519 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
520 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
521 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
522 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
523 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
524 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
525 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
526 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
527 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
528 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
529 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
530 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
531 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
532 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
533 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
534 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
535 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
536 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
537 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
538 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
539 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
540 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
541 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
542 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
543 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
544 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
545 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
546 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
547 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
548 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
549 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
550 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
551 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
552 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
553 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
554 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
555 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
556 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
557 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
558 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
559 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
560 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
561 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
562 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
563 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
564 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
565 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
566 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
567 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
568 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
569 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
570
571// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
572// the final (optional) element of |kCustomSession| with tag number 30.
573static const char kBadSessionExtraField[] =
574 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
575 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
576 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
577 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
578 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
579 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
580 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
581 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
582
583// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
584// the version of |kCustomSession| with 2.
585static const char kBadSessionVersion[] =
586 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
587 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
588 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
589 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
590 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
591 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
592 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
593 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
594
595// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
596// appended.
597static const char kBadSessionTrailingData[] =
598 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
599 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
600 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
601 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
602 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
603 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
604 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
605 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
606
David Benjamin1d77e562015-03-22 17:22:08 -0400607static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400608 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400609 if (!EVP_DecodedLength(&len, strlen(in))) {
610 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400611 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400612 }
613
David Benjamin1d77e562015-03-22 17:22:08 -0400614 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800615 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400616 strlen(in))) {
617 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400618 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400619 }
David Benjamin1d77e562015-03-22 17:22:08 -0400620 out->resize(len);
621 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400622}
623
David Benjamin1d77e562015-03-22 17:22:08 -0400624static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400625 const uint8_t *cptr;
626 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400627
David Benjamin1d77e562015-03-22 17:22:08 -0400628 // Decode the input.
629 std::vector<uint8_t> input;
630 if (!DecodeBase64(&input, input_b64)) {
631 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400632 }
633
David Benjamin1d77e562015-03-22 17:22:08 -0400634 // Verify the SSL_SESSION decodes.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800635 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400636 if (!session) {
637 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400638 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400639 }
640
David Benjamin1d77e562015-03-22 17:22:08 -0400641 // Verify the SSL_SESSION encoding round-trips.
642 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700643 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400644 uint8_t *encoded_raw;
645 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400646 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400647 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400648 }
David Benjamin1d77e562015-03-22 17:22:08 -0400649 encoded.reset(encoded_raw);
650 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500651 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400652 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200653 hexdump(stderr, "Before: ", input.data(), input.size());
654 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400655 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400656 }
David Benjamin3cac4502014-10-21 01:46:30 -0400657
David Benjaminfd67aa82015-06-15 19:41:48 -0400658 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800659 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400660 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800661 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400662 fprintf(stderr, "d2i_SSL_SESSION failed\n");
663 return false;
664 }
665
David Benjamin1d77e562015-03-22 17:22:08 -0400666 // Verify the SSL_SESSION encoding round-trips via the legacy API.
667 int len = i2d_SSL_SESSION(session.get(), NULL);
668 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400669 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400670 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400671 }
672
David Benjamin1d77e562015-03-22 17:22:08 -0400673 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
674 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400675 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400676 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400677 }
David Benjamin1d77e562015-03-22 17:22:08 -0400678
679 ptr = encoded.get();
680 len = i2d_SSL_SESSION(session.get(), &ptr);
681 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400682 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400683 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400684 }
David Benjamin1d77e562015-03-22 17:22:08 -0400685 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400686 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400687 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400688 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500689 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400690 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400691 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400692 }
693
David Benjamin1d77e562015-03-22 17:22:08 -0400694 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400695}
696
David Benjaminf297e022015-05-28 19:55:29 -0400697static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
698 std::vector<uint8_t> input;
699 if (!DecodeBase64(&input, input_b64)) {
700 return false;
701 }
702
703 // Verify that the SSL_SESSION fails to decode.
Adam Langleyc0fc7a12016-12-09 15:05:34 -0800704 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400705 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400706 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400707 return false;
708 }
709 ERR_clear_error();
710 return true;
711}
712
David Benjamin10e664b2016-06-20 22:20:47 -0400713static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400714 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700715 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400716 if (!ctx) {
717 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500718 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400719 if (ctx->min_version != min_version || ctx->max_version != max_version) {
720 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
721 ctx->min_version, ctx->max_version, min_version, max_version);
722 return false;
723 }
724 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500725}
726
David Benjamin1d77e562015-03-22 17:22:08 -0400727static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500728 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
729 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400730 return false;
David Benjamin65226252015-02-05 16:49:47 -0500731 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700732 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400733 if (!rfc_name) {
734 return false;
735 }
David Benjamin67be0482015-04-20 16:19:00 -0400736 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400737 return true;
David Benjamin65226252015-02-05 16:49:47 -0500738}
739
740typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500741 int id;
David Benjamin65226252015-02-05 16:49:47 -0500742 const char *rfc_name;
743} CIPHER_RFC_NAME_TEST;
744
745static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400746 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
747 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
748 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
749 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
750 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
751 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
752 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
753 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
754 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
755 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
756 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
757 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
758 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
759 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
760 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
761 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
762 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
763 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
764 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
765 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
766 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
767 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500768};
769
David Benjamin1d77e562015-03-22 17:22:08 -0400770static bool TestCipherGetRFCName(void) {
771 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400772 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500773 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400774 std::string rfc_name;
775 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
776 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
777 return false;
David Benjamin65226252015-02-05 16:49:47 -0500778 }
David Benjamin1d77e562015-03-22 17:22:08 -0400779 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500780 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400781 rfc_name.c_str(), test->rfc_name);
782 return false;
David Benjamin65226252015-02-05 16:49:47 -0500783 }
David Benjamin65226252015-02-05 16:49:47 -0500784 }
David Benjamin1d77e562015-03-22 17:22:08 -0400785 return true;
David Benjamin65226252015-02-05 16:49:47 -0500786}
787
Steven Valdeza833c352016-11-01 13:39:36 -0400788// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
789// version and ticket length or nullptr on failure.
790static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
791 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400792 std::vector<uint8_t> der;
793 if (!DecodeBase64(&der, kOpenSSLSession)) {
794 return nullptr;
795 }
Steven Valdeza833c352016-11-01 13:39:36 -0400796 bssl::UniquePtr<SSL_SESSION> session(
797 SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400798 if (!session) {
799 return nullptr;
800 }
801
Steven Valdeza833c352016-11-01 13:39:36 -0400802 session->ssl_version = version;
803
David Benjamin422fe082015-07-21 22:03:43 -0400804 // Swap out the ticket for a garbage one.
805 OPENSSL_free(session->tlsext_tick);
806 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
807 if (session->tlsext_tick == nullptr) {
808 return nullptr;
809 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500810 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400811 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400812
813 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500814#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
815 session->time = 1234;
816#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400817 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500818#endif
David Benjamin422fe082015-07-21 22:03:43 -0400819 return session;
820}
821
David Benjaminafc64de2016-07-19 17:12:41 +0200822static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700823 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200824 if (!bio) {
825 return false;
826 }
827 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400828 BIO_up_ref(bio.get());
829 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200830 int ret = SSL_connect(ssl);
831 if (ret > 0) {
832 // SSL_connect should fail without a BIO to write to.
833 return false;
834 }
835 ERR_clear_error();
836
837 const uint8_t *client_hello;
838 size_t client_hello_len;
839 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
840 return false;
841 }
842 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
843 return true;
844}
845
Steven Valdeza833c352016-11-01 13:39:36 -0400846// GetClientHelloLen creates a client SSL connection with the specified version
847// and ticket length. It returns the length of the ClientHello, not including
848// the record header, on success and zero on error.
849static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
850 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700851 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400852 bssl::UniquePtr<SSL_SESSION> session =
853 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400854 if (!ctx || !session) {
855 return 0;
856 }
Steven Valdeza833c352016-11-01 13:39:36 -0400857
858 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700859 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400860 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Steven Valdeza833c352016-11-01 13:39:36 -0400861 !SSL_set_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
862 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400863 return 0;
864 }
Steven Valdeza833c352016-11-01 13:39:36 -0400865
David Benjaminafc64de2016-07-19 17:12:41 +0200866 std::vector<uint8_t> client_hello;
867 if (!GetClientHello(ssl.get(), &client_hello) ||
868 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400869 return 0;
870 }
Steven Valdeza833c352016-11-01 13:39:36 -0400871
David Benjaminafc64de2016-07-19 17:12:41 +0200872 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400873}
874
875struct PaddingTest {
876 size_t input_len, padded_len;
877};
878
879static const PaddingTest kPaddingTests[] = {
880 // ClientHellos of length below 0x100 do not require padding.
881 {0xfe, 0xfe},
882 {0xff, 0xff},
883 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
884 {0x100, 0x200},
885 {0x123, 0x200},
886 {0x1fb, 0x200},
887 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
888 // padding extension takes a minimum of four bytes plus one required content
889 // byte. (To work around yet more server bugs, we avoid empty final
890 // extensions.)
891 {0x1fc, 0x201},
892 {0x1fd, 0x202},
893 {0x1fe, 0x203},
894 {0x1ff, 0x204},
895 // Finally, larger ClientHellos need no padding.
896 {0x200, 0x200},
897 {0x201, 0x201},
898};
899
Steven Valdeza833c352016-11-01 13:39:36 -0400900static bool TestPaddingExtension(uint16_t max_version,
901 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400902 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400903 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400904 if (base_len == 0) {
905 return false;
906 }
907
908 for (const PaddingTest &test : kPaddingTests) {
909 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400910 fprintf(stderr,
911 "Baseline ClientHello too long (max_version = %04x, "
912 "session_version = %04x).\n",
913 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400914 return false;
915 }
916
Steven Valdeza833c352016-11-01 13:39:36 -0400917 size_t padded_len = GetClientHelloLen(max_version, session_version,
918 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400919 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400920 fprintf(stderr,
921 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
922 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400923 static_cast<unsigned>(test.input_len),
924 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400925 static_cast<unsigned>(test.padded_len), max_version,
926 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400927 return false;
928 }
929 }
Steven Valdeza833c352016-11-01 13:39:36 -0400930
David Benjamin422fe082015-07-21 22:03:43 -0400931 return true;
932}
933
David Benjamin1d128f32015-09-08 17:41:40 -0400934// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
935// before configuring as a server.
936static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700937 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400938 if (!ctx) {
939 return false;
940 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700941 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400942 if (!ssl) {
943 return false;
944 }
945
946 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
947 if (stack == nullptr) {
948 return false;
949 }
950 // |SSL_set_client_CA_list| takes ownership.
951 SSL_set_client_CA_list(ssl.get(), stack);
952
953 return SSL_get_client_CA_list(ssl.get()) == stack;
954}
955
David Benjamin0f653952015-10-18 14:28:01 -0400956static void AppendSession(SSL_SESSION *session, void *arg) {
957 std::vector<SSL_SESSION*> *out =
958 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
959 out->push_back(session);
960}
961
962// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
963// order.
964static bool ExpectCache(SSL_CTX *ctx,
965 const std::vector<SSL_SESSION*> &expected) {
966 // Check the linked list.
967 SSL_SESSION *ptr = ctx->session_cache_head;
968 for (SSL_SESSION *session : expected) {
969 if (ptr != session) {
970 return false;
971 }
972 // TODO(davidben): This is an absurd way to denote the end of the list.
973 if (ptr->next ==
974 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
975 ptr = nullptr;
976 } else {
977 ptr = ptr->next;
978 }
979 }
980 if (ptr != nullptr) {
981 return false;
982 }
983
984 // Check the hash table.
985 std::vector<SSL_SESSION*> actual, expected_copy;
986 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
987 expected_copy = expected;
988
989 std::sort(actual.begin(), actual.end());
990 std::sort(expected_copy.begin(), expected_copy.end());
991
992 return actual == expected_copy;
993}
994
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700995static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
996 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -0400997 if (!ret) {
998 return nullptr;
999 }
1000
1001 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001002 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1003 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001004 return ret;
1005}
1006
David Benjamin0f653952015-10-18 14:28:01 -04001007// Test that the internal session cache behaves as expected.
1008static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001009 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001010 if (!ctx) {
1011 return false;
1012 }
1013
1014 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001015 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001016 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001017 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001018 if (!session) {
1019 return false;
1020 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001021 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001022 }
1023
1024 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1025
1026 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001027 for (const auto &session : sessions) {
1028 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001029 return false;
1030 }
1031 }
1032
1033 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001034 std::vector<SSL_SESSION*> expected = {
1035 sessions[9].get(),
1036 sessions[8].get(),
1037 sessions[7].get(),
1038 sessions[6].get(),
1039 sessions[5].get(),
1040 };
David Benjamin0f653952015-10-18 14:28:01 -04001041 if (!ExpectCache(ctx.get(), expected)) {
1042 return false;
1043 }
1044
1045 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001046 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001047 !ExpectCache(ctx.get(), expected)) {
1048 return false;
1049 }
1050
1051 // Although collisions should be impossible (256-bit session IDs), the cache
1052 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001053 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001054 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1055 return false;
1056 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001057 expected = {
1058 collision.get(),
1059 sessions[9].get(),
1060 sessions[8].get(),
1061 sessions[6].get(),
1062 sessions[5].get(),
1063 };
David Benjamin0f653952015-10-18 14:28:01 -04001064 if (!ExpectCache(ctx.get(), expected)) {
1065 return false;
1066 }
1067
1068 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001069 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001070 return false;
1071 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001072 expected = {
1073 collision.get(),
1074 sessions[9].get(),
1075 sessions[8].get(),
1076 sessions[5].get(),
1077 };
David Benjamin0f653952015-10-18 14:28:01 -04001078 if (!ExpectCache(ctx.get(), expected)) {
1079 return false;
1080 }
1081
1082 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001083 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1084 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001085 !ExpectCache(ctx.get(), expected)) {
1086 return false;
1087 }
1088
1089 return true;
1090}
1091
David Benjaminde942382016-02-11 12:02:01 -05001092static uint16_t EpochFromSequence(uint64_t seq) {
1093 return static_cast<uint16_t>(seq >> 48);
1094}
1095
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001096static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001097 static const char kCertPEM[] =
1098 "-----BEGIN CERTIFICATE-----\n"
1099 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1100 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1101 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1102 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1103 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1104 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1105 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1106 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1107 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1108 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1109 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1110 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1111 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1112 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001113 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001114 return bssl::UniquePtr<X509>(
1115 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001116}
1117
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001118static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001119 static const char kKeyPEM[] =
1120 "-----BEGIN RSA PRIVATE KEY-----\n"
1121 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1122 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1123 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1124 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1125 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1126 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1127 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1128 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1129 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1130 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1131 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1132 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1133 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1134 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001135 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1136 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001137 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1138}
1139
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001140static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001141 static const char kCertPEM[] =
1142 "-----BEGIN CERTIFICATE-----\n"
1143 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1144 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1145 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1146 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1147 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1148 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1149 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1150 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1151 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1152 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1153 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001154 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1155 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001156}
1157
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001158static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001159 static const char kKeyPEM[] =
1160 "-----BEGIN PRIVATE KEY-----\n"
1161 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1162 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1163 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1164 "-----END 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 Benjamin0fc37ef2016-08-17 15:29:46 -04001167 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1168}
1169
David Benjamin1444c3a2016-12-20 17:23:11 -05001170static bssl::UniquePtr<X509> GetChainTestCertificate() {
1171 static const char kCertPEM[] =
1172 "-----BEGIN CERTIFICATE-----\n"
1173 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1174 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1175 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1176 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1177 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1178 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1179 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1180 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1181 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1182 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1183 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1184 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1185 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1186 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1187 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1188 "1ngWZ7Ih\n"
1189 "-----END CERTIFICATE-----\n";
1190 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1191 return bssl::UniquePtr<X509>(
1192 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1193}
1194
1195static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1196 static const char kCertPEM[] =
1197 "-----BEGIN CERTIFICATE-----\n"
1198 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1199 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1200 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1201 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1202 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1203 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1204 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1205 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1206 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1207 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1208 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1209 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1210 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1211 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1212 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1213 "-----END CERTIFICATE-----\n";
1214 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1215 return bssl::UniquePtr<X509>(
1216 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1217}
1218
1219static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1220 static const char kKeyPEM[] =
1221 "-----BEGIN PRIVATE KEY-----\n"
1222 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1223 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1224 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1225 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1226 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1227 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1228 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1229 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1230 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1231 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1232 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1233 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1234 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1235 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1236 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1237 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1238 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1239 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1240 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1241 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1242 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1243 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1244 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1245 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1246 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1247 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1248 "-----END PRIVATE KEY-----\n";
1249 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1250 return bssl::UniquePtr<EVP_PKEY>(
1251 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1252}
1253
David Benjaminb79cc842016-12-07 15:57:14 -05001254static bool CompleteHandshakes(SSL *client, SSL *server) {
1255 // Drive both their handshakes to completion.
1256 for (;;) {
1257 int client_ret = SSL_do_handshake(client);
1258 int client_err = SSL_get_error(client, client_ret);
1259 if (client_err != SSL_ERROR_NONE &&
1260 client_err != SSL_ERROR_WANT_READ &&
1261 client_err != SSL_ERROR_WANT_WRITE) {
1262 fprintf(stderr, "Client error: %d\n", client_err);
1263 return false;
1264 }
1265
1266 int server_ret = SSL_do_handshake(server);
1267 int server_err = SSL_get_error(server, server_ret);
1268 if (server_err != SSL_ERROR_NONE &&
1269 server_err != SSL_ERROR_WANT_READ &&
1270 server_err != SSL_ERROR_WANT_WRITE) {
1271 fprintf(stderr, "Server error: %d\n", server_err);
1272 return false;
1273 }
1274
1275 if (client_ret == 1 && server_ret == 1) {
1276 break;
1277 }
1278 }
1279
1280 return true;
1281}
1282
1283static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1284 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001285 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1286 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001287 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001288 if (!client || !server) {
1289 return false;
1290 }
1291 SSL_set_connect_state(client.get());
1292 SSL_set_accept_state(server.get());
1293
David Benjamina20e5352016-08-02 19:09:41 -04001294 SSL_set_session(client.get(), session);
1295
David Benjaminde942382016-02-11 12:02:01 -05001296 BIO *bio1, *bio2;
1297 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1298 return false;
1299 }
1300 // SSL_set_bio takes ownership.
1301 SSL_set_bio(client.get(), bio1, bio1);
1302 SSL_set_bio(server.get(), bio2, bio2);
1303
David Benjaminb79cc842016-12-07 15:57:14 -05001304 if (!CompleteHandshakes(client.get(), server.get())) {
1305 return false;
David Benjaminde942382016-02-11 12:02:01 -05001306 }
1307
David Benjamin686bb192016-05-10 15:15:41 -04001308 *out_client = std::move(client);
1309 *out_server = std::move(server);
1310 return true;
1311}
1312
David Benjamin0fef3052016-11-18 15:11:10 +09001313static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1314 uint16_t version) {
1315 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1316 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1317 if (!server_ctx || !client_ctx ||
1318 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1319 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1320 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1321 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1322 return false;
1323 }
David Benjamin686bb192016-05-10 15:15:41 -04001324
David Benjamin0fef3052016-11-18 15:11:10 +09001325 bssl::UniquePtr<X509> cert = GetTestCertificate();
1326 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1327 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1328 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1329 return false;
1330 }
David Benjamin686bb192016-05-10 15:15:41 -04001331
David Benjamin0fef3052016-11-18 15:11:10 +09001332 bssl::UniquePtr<SSL> client, server;
1333 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1334 server_ctx.get(), nullptr /* no session */)) {
1335 return false;
1336 }
David Benjamin686bb192016-05-10 15:15:41 -04001337
David Benjamin0fef3052016-11-18 15:11:10 +09001338 // Drain any post-handshake messages to ensure there are no unread records
1339 // on either end.
1340 uint8_t byte = 0;
1341 if (SSL_read(client.get(), &byte, 1) > 0 ||
1342 SSL_read(server.get(), &byte, 1) > 0) {
1343 fprintf(stderr, "Received unexpected data.\n");
1344 return false;
1345 }
David Benjaminde942382016-02-11 12:02:01 -05001346
David Benjamin0fef3052016-11-18 15:11:10 +09001347 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1348 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1349 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1350 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001351
David Benjamin0fef3052016-11-18 15:11:10 +09001352 if (is_dtls) {
1353 // Both client and server must be at epoch 1.
1354 if (EpochFromSequence(client_read_seq) != 1 ||
1355 EpochFromSequence(client_write_seq) != 1 ||
1356 EpochFromSequence(server_read_seq) != 1 ||
1357 EpochFromSequence(server_write_seq) != 1) {
1358 fprintf(stderr, "Bad epochs.\n");
1359 return false;
David Benjaminde942382016-02-11 12:02:01 -05001360 }
David Benjamin0fef3052016-11-18 15:11:10 +09001361
1362 // The next record to be written should exceed the largest received.
1363 if (client_write_seq <= server_read_seq ||
1364 server_write_seq <= client_read_seq) {
1365 fprintf(stderr, "Inconsistent sequence numbers.\n");
1366 return false;
1367 }
1368 } else {
1369 // The next record to be written should equal the next to be received.
1370 if (client_write_seq != server_read_seq ||
1371 server_write_seq != client_read_seq) {
1372 fprintf(stderr, "Inconsistent sequence numbers.\n");
1373 return false;
1374 }
1375 }
1376
1377 // Send a record from client to server.
1378 if (SSL_write(client.get(), &byte, 1) != 1 ||
1379 SSL_read(server.get(), &byte, 1) != 1) {
1380 fprintf(stderr, "Could not send byte.\n");
1381 return false;
1382 }
1383
1384 // The client write and server read sequence numbers should have
1385 // incremented.
1386 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1387 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1388 fprintf(stderr, "Sequence numbers did not increment.\n");
1389 return false;
David Benjaminde942382016-02-11 12:02:01 -05001390 }
1391
1392 return true;
1393}
1394
David Benjamin68f37b72016-11-18 15:14:42 +09001395static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1396 uint16_t version) {
1397 // SSL_shutdown is a no-op in DTLS.
1398 if (is_dtls) {
1399 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001400 }
1401
David Benjamin68f37b72016-11-18 15:14:42 +09001402 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1403 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001404 bssl::UniquePtr<X509> cert = GetTestCertificate();
1405 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001406 if (!client_ctx || !server_ctx || !cert || !key ||
1407 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1408 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1409 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1410 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001411 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1412 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1413 return false;
1414 }
1415
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001416 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001417 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001418 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001419 return false;
1420 }
1421
1422 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1423 // one side has shut down.
1424 if (SSL_shutdown(client.get()) != 0) {
1425 fprintf(stderr, "Could not shutdown.\n");
1426 return false;
1427 }
1428
1429 // Reading from the server should consume the EOF.
1430 uint8_t byte;
1431 if (SSL_read(server.get(), &byte, 1) != 0 ||
1432 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1433 fprintf(stderr, "Connection was not shut down cleanly.\n");
1434 return false;
1435 }
1436
1437 // However, the server may continue to write data and then shut down the
1438 // connection.
1439 byte = 42;
1440 if (SSL_write(server.get(), &byte, 1) != 1 ||
1441 SSL_read(client.get(), &byte, 1) != 1 ||
1442 byte != 42) {
1443 fprintf(stderr, "Could not send byte.\n");
1444 return false;
1445 }
1446
1447 // The server may then shutdown the connection.
1448 if (SSL_shutdown(server.get()) != 1 ||
1449 SSL_shutdown(client.get()) != 1) {
1450 fprintf(stderr, "Could not complete shutdown.\n");
1451 return false;
1452 }
1453
1454 return true;
1455}
David Benjamin68f37b72016-11-18 15:14:42 +09001456
Steven Valdez87eab492016-06-27 16:34:59 -04001457static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001458 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1459 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001460 if (!client_ctx || !server_ctx) {
1461 return false;
1462 }
1463
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001464 bssl::UniquePtr<X509> cert = GetTestCertificate();
1465 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001466 if (!cert || !key ||
1467 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1468 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1469 return false;
1470 }
1471
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001472 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001473 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001474 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001475 return false;
1476 }
1477
1478 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001479 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001480 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001481 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001482 }
David Benjamin4501bd52016-08-01 13:39:41 -04001483
Steven Valdez84b5c002016-08-25 16:30:58 -04001484 session1->not_resumable = 0;
1485
Steven Valdez87eab492016-06-27 16:34:59 -04001486 uint8_t *s0_bytes, *s1_bytes;
1487 size_t s0_len, s1_len;
1488
1489 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1490 return false;
1491 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001492 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001493
1494 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1495 return false;
1496 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001497 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001498
David Benjamin17cf2cb2016-12-13 01:07:13 -05001499 return s0_len == s1_len && OPENSSL_memcmp(s0_bytes, s1_bytes, s0_len) == 0;
Steven Valdez87eab492016-06-27 16:34:59 -04001500}
David Benjamin686bb192016-05-10 15:15:41 -04001501
David Benjamin5c0fb882016-06-14 14:03:51 -04001502static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1503 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1504 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1505 SSL_get_wfd(ssl), rfd, wfd);
1506 return false;
1507 }
1508
1509 // The wrapper BIOs are always equal when fds are equal, even if set
1510 // individually.
1511 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1512 fprintf(stderr, "rbio and wbio did not match.\n");
1513 return false;
1514 }
1515
1516 return true;
1517}
1518
1519static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001520 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001521 if (!ctx) {
1522 return false;
1523 }
1524
1525 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001526 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001527 if (!ssl ||
1528 !SSL_set_rfd(ssl.get(), 1) ||
1529 !SSL_set_wfd(ssl.get(), 2) ||
1530 !ExpectFDs(ssl.get(), 1, 2)) {
1531 return false;
1532 }
1533
1534 // Test setting the same FD.
1535 ssl.reset(SSL_new(ctx.get()));
1536 if (!ssl ||
1537 !SSL_set_fd(ssl.get(), 1) ||
1538 !ExpectFDs(ssl.get(), 1, 1)) {
1539 return false;
1540 }
1541
1542 // Test setting the same FD one side at a time.
1543 ssl.reset(SSL_new(ctx.get()));
1544 if (!ssl ||
1545 !SSL_set_rfd(ssl.get(), 1) ||
1546 !SSL_set_wfd(ssl.get(), 1) ||
1547 !ExpectFDs(ssl.get(), 1, 1)) {
1548 return false;
1549 }
1550
1551 // Test setting the same FD in the other order.
1552 ssl.reset(SSL_new(ctx.get()));
1553 if (!ssl ||
1554 !SSL_set_wfd(ssl.get(), 1) ||
1555 !SSL_set_rfd(ssl.get(), 1) ||
1556 !ExpectFDs(ssl.get(), 1, 1)) {
1557 return false;
1558 }
1559
David Benjamin5c0fb882016-06-14 14:03:51 -04001560 // Test changing the read FD partway through.
1561 ssl.reset(SSL_new(ctx.get()));
1562 if (!ssl ||
1563 !SSL_set_fd(ssl.get(), 1) ||
1564 !SSL_set_rfd(ssl.get(), 2) ||
1565 !ExpectFDs(ssl.get(), 2, 1)) {
1566 return false;
1567 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001568
1569 // Test changing the write FD partway through.
1570 ssl.reset(SSL_new(ctx.get()));
1571 if (!ssl ||
1572 !SSL_set_fd(ssl.get(), 1) ||
1573 !SSL_set_wfd(ssl.get(), 2) ||
1574 !ExpectFDs(ssl.get(), 1, 2)) {
1575 return false;
1576 }
1577
1578 // Test a no-op change to the read FD partway through.
1579 ssl.reset(SSL_new(ctx.get()));
1580 if (!ssl ||
1581 !SSL_set_fd(ssl.get(), 1) ||
1582 !SSL_set_rfd(ssl.get(), 1) ||
1583 !ExpectFDs(ssl.get(), 1, 1)) {
1584 return false;
1585 }
1586
1587 // Test a no-op change to the write FD partway through.
1588 ssl.reset(SSL_new(ctx.get()));
1589 if (!ssl ||
1590 !SSL_set_fd(ssl.get(), 1) ||
1591 !SSL_set_wfd(ssl.get(), 1) ||
1592 !ExpectFDs(ssl.get(), 1, 1)) {
1593 return false;
1594 }
1595
1596 // ASan builds will implicitly test that the internal |BIO| reference-counting
1597 // is correct.
1598
1599 return true;
1600}
1601
David Benjamin4501bd52016-08-01 13:39:41 -04001602static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001603 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001604 if (!ctx) {
1605 return false;
1606 }
1607
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001608 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1609 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001610 bio3(BIO_new(BIO_s_mem()));
1611 if (!ssl || !bio1 || !bio2 || !bio3) {
1612 return false;
1613 }
1614
1615 // SSL_set_bio takes one reference when the parameters are the same.
1616 BIO_up_ref(bio1.get());
1617 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1618
1619 // Repeating the call does nothing.
1620 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1621
1622 // It takes one reference each when the parameters are different.
1623 BIO_up_ref(bio2.get());
1624 BIO_up_ref(bio3.get());
1625 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1626
1627 // Repeating the call does nothing.
1628 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1629
1630 // It takes one reference when changing only wbio.
1631 BIO_up_ref(bio1.get());
1632 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1633
1634 // It takes one reference when changing only rbio and the two are different.
1635 BIO_up_ref(bio3.get());
1636 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1637
1638 // If setting wbio to rbio, it takes no additional references.
1639 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1640
1641 // From there, wbio may be switched to something else.
1642 BIO_up_ref(bio1.get());
1643 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1644
1645 // If setting rbio to wbio, it takes no additional references.
1646 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1647
1648 // From there, rbio may be switched to something else, but, for historical
1649 // reasons, it takes a reference to both parameters.
1650 BIO_up_ref(bio1.get());
1651 BIO_up_ref(bio2.get());
1652 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1653
1654 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1655 // is correct.
1656 return true;
1657}
1658
David Benjamin25490f22016-07-14 00:22:54 -04001659static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1660
David Benjamin0fef3052016-11-18 15:11:10 +09001661static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1662 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001663 bssl::UniquePtr<X509> cert = GetTestCertificate();
1664 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001665 if (!cert || !key) {
1666 return false;
1667 }
1668
David Benjamin0fef3052016-11-18 15:11:10 +09001669 // Configure both client and server to accept any certificate.
1670 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1671 if (!ctx ||
1672 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1673 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1674 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1675 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1676 return false;
1677 }
1678 SSL_CTX_set_verify(
1679 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1680 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001681
David Benjamin0fef3052016-11-18 15:11:10 +09001682 bssl::UniquePtr<SSL> client, server;
1683 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1684 nullptr /* no session */)) {
1685 return false;
1686 }
David Benjaminadd5e522016-07-14 00:33:24 -04001687
David Benjamin0fef3052016-11-18 15:11:10 +09001688 // Client and server should both see the leaf certificate.
1689 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1690 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1691 fprintf(stderr, "Server peer certificate did not match.\n");
1692 return false;
1693 }
David Benjaminadd5e522016-07-14 00:33:24 -04001694
David Benjamin0fef3052016-11-18 15:11:10 +09001695 peer.reset(SSL_get_peer_certificate(client.get()));
1696 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1697 fprintf(stderr, "Client peer certificate did not match.\n");
1698 return false;
1699 }
David Benjaminadd5e522016-07-14 00:33:24 -04001700
David Benjamin0fef3052016-11-18 15:11:10 +09001701 // However, for historical reasons, the chain includes the leaf on the
1702 // client, but does not on the server.
1703 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1704 fprintf(stderr, "Client peer chain was incorrect.\n");
1705 return false;
1706 }
David Benjaminadd5e522016-07-14 00:33:24 -04001707
David Benjamin0fef3052016-11-18 15:11:10 +09001708 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1709 fprintf(stderr, "Server peer chain was incorrect.\n");
1710 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001711 }
1712
1713 return true;
1714}
1715
David Benjamin0fef3052016-11-18 15:11:10 +09001716static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1717 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001718 bssl::UniquePtr<X509> cert = GetTestCertificate();
1719 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001720 if (!cert || !key) {
1721 return false;
1722 }
1723
1724 uint8_t *cert_der = NULL;
1725 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1726 if (cert_der_len < 0) {
1727 return false;
1728 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001729 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001730
1731 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1732 SHA256(cert_der, cert_der_len, cert_sha256);
1733
David Benjamin0fef3052016-11-18 15:11:10 +09001734 // Configure both client and server to accept any certificate, but the
1735 // server must retain only the SHA-256 of the peer.
1736 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1737 if (!ctx ||
1738 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1739 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1740 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1741 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1742 return false;
1743 }
1744 SSL_CTX_set_verify(
1745 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1746 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1747 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001748
David Benjamin0fef3052016-11-18 15:11:10 +09001749 bssl::UniquePtr<SSL> client, server;
1750 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1751 nullptr /* no session */)) {
1752 return false;
1753 }
David Benjamin25490f22016-07-14 00:22:54 -04001754
David Benjamin0fef3052016-11-18 15:11:10 +09001755 // The peer certificate has been dropped.
1756 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1757 if (peer) {
1758 fprintf(stderr, "Peer certificate was retained.\n");
1759 return false;
1760 }
David Benjamin25490f22016-07-14 00:22:54 -04001761
David Benjamin0fef3052016-11-18 15:11:10 +09001762 SSL_SESSION *session = SSL_get_session(server.get());
1763 if (!session->peer_sha256_valid) {
1764 fprintf(stderr, "peer_sha256_valid was not set.\n");
1765 return false;
1766 }
David Benjamin25490f22016-07-14 00:22:54 -04001767
David Benjamin17cf2cb2016-12-13 01:07:13 -05001768 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1769 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001770 fprintf(stderr, "peer_sha256 did not match.\n");
1771 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001772 }
1773
1774 return true;
1775}
1776
David Benjaminafc64de2016-07-19 17:12:41 +02001777static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1778 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001779 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001780 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001781 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001782 // Our default cipher list varies by CPU capabilities, so manually place
1783 // the ChaCha20 ciphers in front.
1784 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001785 return false;
1786 }
David Benjamin2dc02042016-09-19 19:57:37 -04001787
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001788 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001789 if (!ssl) {
1790 return false;
1791 }
1792 std::vector<uint8_t> client_hello;
1793 if (!GetClientHello(ssl.get(), &client_hello)) {
1794 return false;
1795 }
1796
1797 // Zero the client_random.
1798 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1799 1 + 3 + // handshake message header
1800 2; // client_version
1801 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1802 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1803 return false;
1804 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001805 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001806
1807 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001808 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001809 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1810 fprintf(stderr, "Got:\n\t");
1811 for (size_t i = 0; i < client_hello.size(); i++) {
1812 fprintf(stderr, "0x%02x, ", client_hello[i]);
1813 }
1814 fprintf(stderr, "\nWanted:\n\t");
1815 for (size_t i = 0; i < expected_len; i++) {
1816 fprintf(stderr, "0x%02x, ", expected[i]);
1817 }
1818 fprintf(stderr, "\n");
1819 return false;
1820 }
1821
1822 return true;
1823}
1824
1825// Tests that our ClientHellos do not change unexpectedly.
1826static bool TestClientHello() {
1827 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001828 0x16,
1829 0x03, 0x00,
1830 0x00, 0x3f,
1831 0x01,
1832 0x00, 0x00, 0x3b,
1833 0x03, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00,
1839 0x00, 0x14,
1840 0xc0, 0x09,
1841 0xc0, 0x13,
1842 0x00, 0x33,
1843 0xc0, 0x0a,
1844 0xc0, 0x14,
1845 0x00, 0x39,
1846 0x00, 0x2f,
1847 0x00, 0x35,
1848 0x00, 0x0a,
1849 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001850 };
1851 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1852 sizeof(kSSL3ClientHello))) {
1853 return false;
1854 }
1855
1856 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001857 0x16,
1858 0x03, 0x01,
1859 0x00, 0x5e,
1860 0x01,
1861 0x00, 0x00, 0x5a,
1862 0x03, 0x01,
1863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00,
1868 0x00, 0x12,
1869 0xc0, 0x09,
1870 0xc0, 0x13,
1871 0x00, 0x33,
1872 0xc0, 0x0a,
1873 0xc0, 0x14,
1874 0x00, 0x39,
1875 0x00, 0x2f,
1876 0x00, 0x35,
1877 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001878 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1879 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1880 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1881 };
1882 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1883 sizeof(kTLS1ClientHello))) {
1884 return false;
1885 }
1886
1887 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001888 0x16,
1889 0x03, 0x01,
1890 0x00, 0x5e,
1891 0x01,
1892 0x00, 0x00, 0x5a,
1893 0x03, 0x02,
1894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898 0x00,
1899 0x00, 0x12,
1900 0xc0, 0x09,
1901 0xc0, 0x13,
1902 0x00, 0x33,
1903 0xc0, 0x0a,
1904 0xc0, 0x14,
1905 0x00, 0x39,
1906 0x00, 0x2f,
1907 0x00, 0x35,
1908 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001909 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1910 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1911 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1912 };
1913 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1914 sizeof(kTLS11ClientHello))) {
1915 return false;
1916 }
1917
1918 static const uint8_t kTLS12ClientHello[] = {
Adam Langley2e839242017-01-19 15:12:44 -08001919 0x16, 0x03, 0x01, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x96, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001920 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Adam Langley2e839242017-01-19 15:12:44 -08001922 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xcc, 0xa9,
1923 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e, 0xc0, 0x2c, 0xc0, 0x30,
1924 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0x00, 0x33,
1925 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x39,
1926 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
1927 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
1928 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1929 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1930 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1931 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1932 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001933 };
1934 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1935 sizeof(kTLS12ClientHello))) {
1936 return false;
1937 }
1938
1939 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1940 // implementation has settled enough that it won't change.
1941
1942 return true;
1943}
1944
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001945static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001946
1947static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1948 // Save the most recent session.
1949 g_last_session.reset(session);
1950 return 1;
1951}
1952
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001953static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001954 SSL_CTX *server_ctx) {
1955 g_last_session = nullptr;
1956 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1957
1958 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001959 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001960 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1961 nullptr /* no session */)) {
1962 fprintf(stderr, "Failed to connect client and server.\n");
1963 return nullptr;
1964 }
1965
1966 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1967 SSL_read(client.get(), nullptr, 0);
1968
1969 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1970
1971 if (!g_last_session) {
1972 fprintf(stderr, "Client did not receive a session.\n");
1973 return nullptr;
1974 }
1975 return std::move(g_last_session);
1976}
1977
1978static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1979 SSL_SESSION *session,
1980 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001981 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001982 if (!ConnectClientAndServer(&client, &server, client_ctx,
1983 server_ctx, session)) {
1984 fprintf(stderr, "Failed to connect client and server.\n");
1985 return false;
1986 }
1987
1988 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1989 fprintf(stderr, "Client and server were inconsistent.\n");
1990 return false;
1991 }
1992
1993 bool was_reused = !!SSL_session_reused(client.get());
1994 if (was_reused != reused) {
1995 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1996 was_reused ? "" : " not");
1997 return false;
1998 }
1999
2000 return true;
2001}
2002
David Benjamin3c51d9b2016-11-01 17:50:42 -04002003static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2004 SSL_CTX *server_ctx,
2005 SSL_SESSION *session) {
2006 g_last_session = nullptr;
2007 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2008
2009 bssl::UniquePtr<SSL> client, server;
2010 if (!ConnectClientAndServer(&client, &server, client_ctx,
2011 server_ctx, session)) {
2012 fprintf(stderr, "Failed to connect client and server.\n");
2013 return nullptr;
2014 }
2015
2016 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2017 fprintf(stderr, "Client and server were inconsistent.\n");
2018 return nullptr;
2019 }
2020
2021 if (!SSL_session_reused(client.get())) {
2022 fprintf(stderr, "Session was not reused.\n");
2023 return nullptr;
2024 }
2025
2026 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2027 SSL_read(client.get(), nullptr, 0);
2028
2029 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2030
2031 if (!g_last_session) {
2032 fprintf(stderr, "Client did not receive a renewed session.\n");
2033 return nullptr;
2034 }
2035 return std::move(g_last_session);
2036}
2037
David Benjamina933c382016-10-28 00:10:03 -04002038static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2039 static const uint8_t kContext[] = {3};
2040
2041 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2042 return SSL_TLSEXT_ERR_ALERT_FATAL;
2043 }
2044
2045 return SSL_TLSEXT_ERR_OK;
2046}
2047
David Benjamin731058e2016-12-03 23:15:13 -05002048static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04002049 static const uint8_t kContext[] = {3};
2050
David Benjamin731058e2016-12-03 23:15:13 -05002051 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2052 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04002053 return -1;
2054 }
2055
2056 return 1;
2057}
2058
David Benjamin0fef3052016-11-18 15:11:10 +09002059static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2060 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002061 bssl::UniquePtr<X509> cert = GetTestCertificate();
2062 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002063 if (!cert || !key) {
2064 return false;
2065 }
2066
2067 static const uint8_t kContext1[] = {1};
2068 static const uint8_t kContext2[] = {2};
2069
David Benjamin0fef3052016-11-18 15:11:10 +09002070 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2071 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2072 if (!server_ctx || !client_ctx ||
2073 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2074 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2075 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2076 sizeof(kContext1)) ||
2077 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2078 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2079 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2080 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2081 return false;
2082 }
David Benjamina20e5352016-08-02 19:09:41 -04002083
David Benjamin0fef3052016-11-18 15:11:10 +09002084 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2085 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002086
David Benjamin0fef3052016-11-18 15:11:10 +09002087 bssl::UniquePtr<SSL_SESSION> session =
2088 CreateClientSession(client_ctx.get(), server_ctx.get());
2089 if (!session) {
2090 fprintf(stderr, "Error getting session.\n");
2091 return false;
2092 }
David Benjamina20e5352016-08-02 19:09:41 -04002093
David Benjamin0fef3052016-11-18 15:11:10 +09002094 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2095 true /* expect session reused */)) {
2096 fprintf(stderr, "Error resuming session.\n");
2097 return false;
2098 }
David Benjamina20e5352016-08-02 19:09:41 -04002099
David Benjamin0fef3052016-11-18 15:11:10 +09002100 // Change the session ID context.
2101 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2102 sizeof(kContext2))) {
2103 return false;
2104 }
David Benjamina20e5352016-08-02 19:09:41 -04002105
David Benjamin0fef3052016-11-18 15:11:10 +09002106 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2107 false /* expect session not reused */)) {
2108 fprintf(stderr, "Error connecting with a different context.\n");
2109 return false;
2110 }
David Benjamina933c382016-10-28 00:10:03 -04002111
David Benjamin0fef3052016-11-18 15:11:10 +09002112 // Change the session ID context back and install an SNI callback to switch
2113 // it.
2114 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2115 sizeof(kContext1))) {
2116 return false;
2117 }
David Benjamina933c382016-10-28 00:10:03 -04002118
David Benjamin0fef3052016-11-18 15:11:10 +09002119 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2120 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002121
David Benjamin0fef3052016-11-18 15:11:10 +09002122 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2123 false /* expect session not reused */)) {
2124 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2125 return false;
2126 }
David Benjamina933c382016-10-28 00:10:03 -04002127
David Benjamin0fef3052016-11-18 15:11:10 +09002128 // Switch the session ID context with the early callback instead.
2129 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2130 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2131 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002132
David Benjamin0fef3052016-11-18 15:11:10 +09002133 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2134 false /* expect session not reused */)) {
2135 fprintf(stderr,
2136 "Error connecting with a context switch on early callback.\n");
2137 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002138 }
2139
2140 return true;
2141}
2142
David Benjamin721e8b72016-08-03 13:13:17 -04002143static timeval g_current_time;
2144
2145static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2146 *out_clock = g_current_time;
2147}
2148
David Benjamin3c51d9b2016-11-01 17:50:42 -04002149static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2150 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2151 int encrypt) {
2152 static const uint8_t kZeros[16] = {0};
2153
2154 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002155 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002156 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002157 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002158 return 0;
2159 }
2160
2161 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2162 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2163 return -1;
2164 }
2165
2166 // Returning two from the callback in decrypt mode renews the
2167 // session in TLS 1.2 and below.
2168 return encrypt ? 1 : 2;
2169}
2170
David Benjamin123db572016-11-03 16:59:25 -04002171static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002172 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2173 return false;
2174 }
2175
David Benjamin123db572016-11-03 16:59:25 -04002176 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2177 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2178 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2179
David Benjamin9b63f292016-11-15 00:44:05 -05002180#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2181 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002182 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002183#else
2184 static const uint8_t kZeros[16] = {0};
2185 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002186 bssl::ScopedEVP_CIPHER_CTX ctx;
2187 int len1, len2;
2188 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2189 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2190 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2191 return false;
2192 }
2193
2194 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002195#endif
David Benjamin123db572016-11-03 16:59:25 -04002196
2197 bssl::UniquePtr<SSL_SESSION> server_session(
2198 SSL_SESSION_from_bytes(plaintext.get(), len));
2199 if (!server_session) {
2200 return false;
2201 }
2202
2203 *out = server_session->time;
2204 return true;
2205}
2206
David Benjamin0fef3052016-11-18 15:11:10 +09002207static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2208 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002209 bssl::UniquePtr<X509> cert = GetTestCertificate();
2210 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002211 if (!cert || !key) {
2212 return false;
2213 }
2214
David Benjamin0fef3052016-11-18 15:11:10 +09002215 for (bool server_test : std::vector<bool>{false, true}) {
2216 static const int kStartTime = 1000;
2217 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002218
David Benjamin0fef3052016-11-18 15:11:10 +09002219 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2220 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2221 if (!server_ctx || !client_ctx ||
2222 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2223 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2224 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2225 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2226 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2227 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2228 return false;
2229 }
2230
2231 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2232 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2233
2234 // Both client and server must enforce session timeouts.
2235 if (server_test) {
2236 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2237 } else {
2238 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
2239 }
2240
2241 // Configure a ticket callback which renews tickets.
2242 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2243
2244 bssl::UniquePtr<SSL_SESSION> session =
2245 CreateClientSession(client_ctx.get(), server_ctx.get());
2246 if (!session) {
2247 fprintf(stderr, "Error getting session.\n");
2248 return false;
2249 }
2250
2251 // Advance the clock just behind the timeout.
2252 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT - 1;
2253
2254 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2255 true /* expect session reused */)) {
2256 fprintf(stderr, "Error resuming session.\n");
2257 return false;
2258 }
2259
2260 // Advance the clock one more second.
2261 g_current_time.tv_sec++;
2262
2263 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2264 false /* expect session not reused */)) {
2265 fprintf(stderr, "Error resuming session.\n");
2266 return false;
2267 }
2268
2269 // Rewind the clock to before the session was minted.
2270 g_current_time.tv_sec = kStartTime - 1;
2271
2272 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2273 false /* expect session not reused */)) {
2274 fprintf(stderr, "Error resuming session.\n");
2275 return false;
2276 }
2277
2278 // SSL 3.0 cannot renew sessions.
2279 if (version == SSL3_VERSION) {
2280 continue;
2281 }
2282
2283 // Renew the session 10 seconds before expiration.
2284 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 10;
2285 bssl::UniquePtr<SSL_SESSION> new_session =
2286 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2287 if (!new_session) {
2288 fprintf(stderr, "Error renewing session.\n");
2289 return false;
2290 }
2291
2292 // This new session is not the same object as before.
2293 if (session.get() == new_session.get()) {
2294 fprintf(stderr, "New and old sessions alias.\n");
2295 return false;
2296 }
2297
2298 // Check the sessions have timestamps measured from issuance.
2299 long session_time = 0;
2300 if (server_test) {
2301 if (!GetServerTicketTime(&session_time, new_session.get())) {
2302 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002303 return false;
2304 }
David Benjamin0fef3052016-11-18 15:11:10 +09002305 } else {
2306 session_time = new_session->time;
2307 }
David Benjamin721e8b72016-08-03 13:13:17 -04002308
David Benjamin0fef3052016-11-18 15:11:10 +09002309 if (session_time != g_current_time.tv_sec) {
2310 fprintf(stderr, "New session is not measured from issuance.\n");
2311 return false;
2312 }
David Benjamin721e8b72016-08-03 13:13:17 -04002313
David Benjamin0fef3052016-11-18 15:11:10 +09002314 // The new session is usable just before the old expiration.
2315 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT - 1;
2316 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2317 new_session.get(),
2318 true /* expect session reused */)) {
2319 fprintf(stderr, "Error resuming renewed session.\n");
2320 return false;
2321 }
David Benjamin721e8b72016-08-03 13:13:17 -04002322
David Benjamin0fef3052016-11-18 15:11:10 +09002323 // Renewal does not extend the lifetime, so it is not usable beyond the
2324 // old expiration.
2325 g_current_time.tv_sec = kStartTime + SSL_DEFAULT_SESSION_TIMEOUT + 1;
2326 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2327 new_session.get(),
2328 false /* expect session not reused */)) {
2329 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2330 return false;
David Benjamin1b22f852016-10-27 16:36:32 -04002331 }
David Benjamin721e8b72016-08-03 13:13:17 -04002332 }
2333
2334 return true;
2335}
2336
Alessandro Ghedinibf483642016-11-22 18:56:46 +00002337static int SetSessionTimeoutCallback(SSL *ssl, void *arg) {
2338 long timeout = *(long *) arg;
2339 SSL_set_session_timeout(ssl, timeout);
2340 return 1;
2341}
2342
2343static bool TestSessionTimeoutCertCallback(bool is_dtls,
2344 const SSL_METHOD *method,
2345 uint16_t version) {
2346 static const int kStartTime = 1000;
2347 g_current_time.tv_sec = kStartTime;
2348
2349 bssl::UniquePtr<X509> cert = GetTestCertificate();
2350 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2351 if (!cert || !key) {
2352 return false;
2353 }
2354
2355 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2356 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2357 if (!server_ctx || !client_ctx ||
2358 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2359 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2360 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2361 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2362 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2363 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2364 return false;
2365 }
2366
2367 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2368 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2369
2370 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2371
2372 long timeout = 25;
2373 SSL_CTX_set_cert_cb(server_ctx.get(), SetSessionTimeoutCallback, &timeout);
2374
2375 bssl::UniquePtr<SSL_SESSION> session =
2376 CreateClientSession(client_ctx.get(), server_ctx.get());
2377 if (!session) {
2378 fprintf(stderr, "Error getting session.\n");
2379 return false;
2380 }
2381
2382 // Advance the clock just behind the timeout.
2383 g_current_time.tv_sec += timeout - 1;
2384
2385 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2386 true /* expect session reused */)) {
2387 fprintf(stderr, "Error resuming session.\n");
2388 return false;
2389 }
2390
2391 // Advance the clock one more second.
2392 g_current_time.tv_sec++;
2393
2394 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2395 false /* expect session not reused */)) {
2396 fprintf(stderr, "Error resuming session.\n");
2397 return false;
2398 }
2399
2400 // Set session timeout to 0 to disable resumption.
2401 timeout = 0;
2402 g_current_time.tv_sec = kStartTime;
2403
2404 bssl::UniquePtr<SSL_SESSION> not_resumable_session =
2405 CreateClientSession(client_ctx.get(), server_ctx.get());
2406 if (!not_resumable_session) {
2407 fprintf(stderr, "Error getting session.\n");
2408 return false;
2409 }
2410
2411 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2412 not_resumable_session.get(),
2413 false /* expect session not reused */)) {
2414 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2415 return false;
2416 }
2417
2418 // Set both context and connection (via callback) default session timeout.
2419 // The connection one is the one that ends up being used.
2420 timeout = 25;
2421 g_current_time.tv_sec = kStartTime;
2422
2423 SSL_CTX_set_timeout(server_ctx.get(), timeout - 10);
2424
2425 bssl::UniquePtr<SSL_SESSION> ctx_and_cb_session =
2426 CreateClientSession(client_ctx.get(), server_ctx.get());
2427 if (!ctx_and_cb_session) {
2428 fprintf(stderr, "Error getting session.\n");
2429 return false;
2430 }
2431
2432 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2433 ctx_and_cb_session.get(),
2434 true /* expect session reused */)) {
2435 fprintf(stderr, "Error resuming session with timeout of 0.\n");
2436 return false;
2437 }
2438
2439 // Advance the clock just behind the timeout.
2440 g_current_time.tv_sec += timeout - 1;
2441
2442 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2443 ctx_and_cb_session.get(),
2444 true /* expect session reused */)) {
2445 fprintf(stderr, "Error resuming session.\n");
2446 return false;
2447 }
2448
2449 // Advance the clock one more second.
2450 g_current_time.tv_sec++;
2451
2452 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2453 ctx_and_cb_session.get(),
2454 false /* expect session not reused */)) {
2455 fprintf(stderr, "Error resuming session.\n");
2456 return false;
2457 }
2458
2459 return true;
2460}
2461
David Benjamin0fc37ef2016-08-17 15:29:46 -04002462static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2463 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2464 SSL_set_SSL_CTX(ssl, ctx);
2465 return SSL_TLSEXT_ERR_OK;
2466}
2467
David Benjamin0fef3052016-11-18 15:11:10 +09002468static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2469 uint16_t version) {
2470 // SSL 3.0 lacks extensions.
2471 if (version == SSL3_VERSION) {
2472 return true;
2473 }
2474
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002475 bssl::UniquePtr<X509> cert = GetTestCertificate();
2476 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2477 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2478 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002479 if (!cert || !key || !cert2 || !key2) {
2480 return false;
2481 }
2482
David Benjamin0fef3052016-11-18 15:11:10 +09002483 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2484 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002485
David Benjamin0fef3052016-11-18 15:11:10 +09002486 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2487 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2488 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2489 if (!server_ctx || !server_ctx2 || !client_ctx ||
2490 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2491 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2492 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2493 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2494 // Historically signing preferences would be lost in some cases with the
2495 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2496 // this doesn't happen when |version| is TLS 1.2, configure the private
2497 // key to only sign SHA-256.
2498 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2499 1) ||
2500 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2501 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2502 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2503 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2504 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2505 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2506 return false;
2507 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002508
David Benjamin0fef3052016-11-18 15:11:10 +09002509 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2510 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002511
David Benjamin0fef3052016-11-18 15:11:10 +09002512 bssl::UniquePtr<SSL> client, server;
2513 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2514 server_ctx.get(), nullptr)) {
2515 fprintf(stderr, "Handshake failed.\n");
2516 return false;
2517 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518
David Benjamin0fef3052016-11-18 15:11:10 +09002519 // The client should have received |cert2|.
2520 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2521 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2522 fprintf(stderr, "Incorrect certificate received.\n");
2523 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002524 }
2525
2526 return true;
2527}
2528
David Benjamin731058e2016-12-03 23:15:13 -05002529static int SetMaxVersion(const SSL_CLIENT_HELLO *client_hello) {
2530 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002531 return -1;
2532 }
2533
David Benjamin99620572016-08-30 00:35:36 -04002534 return 1;
2535}
2536
2537// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2538// maximum version.
2539static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002540 bssl::UniquePtr<X509> cert = GetTestCertificate();
2541 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2542 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2543 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002544 if (!cert || !key || !server_ctx || !client_ctx ||
2545 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002546 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002547 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2548 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002549 return false;
2550 }
2551
David Benjamin99620572016-08-30 00:35:36 -04002552 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2553
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002554 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002555 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2556 server_ctx.get(), nullptr)) {
2557 return false;
2558 }
2559
2560 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2561 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2562 return false;
2563 }
2564
2565 return true;
2566}
2567
David Benjamin2dc02042016-09-19 19:57:37 -04002568static bool TestSetVersion() {
2569 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2570 if (!ctx) {
2571 return false;
2572 }
2573
David Benjamine4706902016-09-20 15:12:23 -04002574 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2575 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2576 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2577 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002578 fprintf(stderr, "Could not set valid TLS version.\n");
2579 return false;
2580 }
2581
David Benjamine4706902016-09-20 15:12:23 -04002582 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2583 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2584 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2585 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2586 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2587 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002588 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2589 return false;
2590 }
2591
David Benjamine34bcc92016-09-21 16:53:09 -04002592 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2593 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2594 fprintf(stderr, "Could not set default TLS version.\n");
2595 return false;
2596 }
2597
2598 if (ctx->min_version != SSL3_VERSION ||
2599 ctx->max_version != TLS1_2_VERSION) {
2600 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2601 ctx->min_version, ctx->max_version);
2602 return false;
2603 }
2604
David Benjamin2dc02042016-09-19 19:57:37 -04002605 ctx.reset(SSL_CTX_new(DTLS_method()));
2606 if (!ctx) {
2607 return false;
2608 }
2609
David Benjamine4706902016-09-20 15:12:23 -04002610 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2611 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2612 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2613 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002614 fprintf(stderr, "Could not set valid DTLS version.\n");
2615 return false;
2616 }
2617
David Benjamine4706902016-09-20 15:12:23 -04002618 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2619 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2620 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2621 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2622 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2623 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2624 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2625 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002626 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2627 return false;
2628 }
2629
David Benjamine34bcc92016-09-21 16:53:09 -04002630 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2631 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2632 fprintf(stderr, "Could not set default DTLS version.\n");
2633 return false;
2634 }
2635
2636 if (ctx->min_version != TLS1_1_VERSION ||
2637 ctx->max_version != TLS1_2_VERSION) {
2638 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2639 ctx->min_version, ctx->max_version);
2640 return false;
2641 }
2642
David Benjamin2dc02042016-09-19 19:57:37 -04002643 return true;
2644}
2645
David Benjamin458334a2016-12-15 13:53:25 -05002646static const char *GetVersionName(uint16_t version) {
2647 switch (version) {
2648 case SSL3_VERSION:
2649 return "SSLv3";
2650 case TLS1_VERSION:
2651 return "TLSv1";
2652 case TLS1_1_VERSION:
2653 return "TLSv1.1";
2654 case TLS1_2_VERSION:
2655 return "TLSv1.2";
2656 case TLS1_3_VERSION:
2657 return "TLSv1.3";
2658 case DTLS1_VERSION:
2659 return "DTLSv1";
2660 case DTLS1_2_VERSION:
2661 return "DTLSv1.2";
2662 default:
2663 return "???";
2664 }
2665}
2666
David Benjamin0fef3052016-11-18 15:11:10 +09002667static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2668 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002669 bssl::UniquePtr<X509> cert = GetTestCertificate();
2670 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2671 if (!cert || !key) {
2672 return false;
2673 }
2674
David Benjamin0fef3052016-11-18 15:11:10 +09002675 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2676 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2677 bssl::UniquePtr<SSL> client, server;
2678 if (!server_ctx || !client_ctx ||
2679 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2680 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2681 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2682 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2683 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2684 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2685 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2686 server_ctx.get(), nullptr /* no session */)) {
2687 fprintf(stderr, "Failed to connect.\n");
2688 return false;
2689 }
David Benjamincb18ac22016-09-27 14:09:15 -04002690
David Benjamin0fef3052016-11-18 15:11:10 +09002691 if (SSL_version(client.get()) != version ||
2692 SSL_version(server.get()) != version) {
2693 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2694 SSL_version(client.get()), SSL_version(server.get()), version);
2695 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002696 }
2697
David Benjamin458334a2016-12-15 13:53:25 -05002698 // Test the version name is reported as expected.
2699 const char *version_name = GetVersionName(version);
2700 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2701 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2702 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2703 SSL_get_version(client.get()), SSL_get_version(server.get()),
2704 version_name);
2705 return false;
2706 }
2707
2708 // Test SSL_SESSION reports the same name.
2709 const char *client_name =
2710 SSL_SESSION_get_version(SSL_get_session(client.get()));
2711 const char *server_name =
2712 SSL_SESSION_get_version(SSL_get_session(server.get()));
2713 if (strcmp(version_name, client_name) != 0 ||
2714 strcmp(version_name, server_name) != 0) {
2715 fprintf(stderr,
2716 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2717 client_name, server_name, version_name);
2718 return false;
2719 }
2720
David Benjamincb18ac22016-09-27 14:09:15 -04002721 return true;
2722}
2723
David Benjamin9ef31f02016-10-31 18:01:13 -04002724// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2725// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002726static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2727 uint16_t version) {
2728 // SSL 3.0 lacks extensions.
2729 if (version == SSL3_VERSION) {
2730 return true;
2731 }
2732
David Benjamin9ef31f02016-10-31 18:01:13 -04002733 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2734
2735 bssl::UniquePtr<X509> cert = GetTestCertificate();
2736 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2737 if (!cert || !key) {
2738 return false;
2739 }
2740
David Benjamin0fef3052016-11-18 15:11:10 +09002741 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2742 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2743 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2744 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2745 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2746 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2747 0) {
2748 return false;
2749 }
2750
2751 // The ALPN callback does not fail the handshake on error, so have the
2752 // callback write a boolean.
2753 std::pair<uint16_t, bool> callback_state(version, false);
2754 SSL_CTX_set_alpn_select_cb(
2755 ctx.get(),
2756 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2757 unsigned in_len, void *arg) -> int {
2758 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2759 if (SSL_get_pending_cipher(ssl) != nullptr &&
2760 SSL_version(ssl) == state->first) {
2761 state->second = true;
2762 }
2763 return SSL_TLSEXT_ERR_NOACK;
2764 },
2765 &callback_state);
2766
2767 bssl::UniquePtr<SSL> client, server;
2768 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2769 nullptr /* no session */)) {
2770 return false;
2771 }
2772
2773 if (!callback_state.second) {
2774 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2775 return false;
2776 }
2777
2778 return true;
2779}
2780
David Benjaminb79cc842016-12-07 15:57:14 -05002781static bool TestSSLClearSessionResumption(bool is_dtls,
2782 const SSL_METHOD *method,
2783 uint16_t version) {
2784 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2785 // API pattern.
2786 if (version == TLS1_3_VERSION) {
2787 return true;
2788 }
2789
2790 bssl::UniquePtr<X509> cert = GetTestCertificate();
2791 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2792 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2793 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2794 if (!cert || !key || !server_ctx || !client_ctx ||
2795 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2796 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2797 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2798 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2799 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2800 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2801 return false;
2802 }
2803
2804 // Connect a client and a server.
2805 bssl::UniquePtr<SSL> client, server;
2806 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2807 server_ctx.get(), nullptr /* no session */)) {
2808 return false;
2809 }
2810
2811 if (SSL_session_reused(client.get()) ||
2812 SSL_session_reused(server.get())) {
2813 fprintf(stderr, "Session unexpectedly reused.\n");
2814 return false;
2815 }
2816
2817 // Reset everything.
2818 if (!SSL_clear(client.get()) ||
2819 !SSL_clear(server.get())) {
2820 fprintf(stderr, "SSL_clear failed.\n");
2821 return false;
2822 }
2823
2824 // Attempt to connect a second time.
2825 if (!CompleteHandshakes(client.get(), server.get())) {
2826 fprintf(stderr, "Could not reuse SSL objects.\n");
2827 return false;
2828 }
2829
2830 // |SSL_clear| should implicitly offer the previous session to the server.
2831 if (!SSL_session_reused(client.get()) ||
2832 !SSL_session_reused(server.get())) {
2833 fprintf(stderr, "Session was not reused in second try.\n");
2834 return false;
2835 }
2836
2837 return true;
2838}
2839
David Benjamin1444c3a2016-12-20 17:23:11 -05002840static bool ChainsEqual(STACK_OF(X509) *chain,
2841 const std::vector<X509 *> &expected) {
2842 if (sk_X509_num(chain) != expected.size()) {
2843 return false;
2844 }
2845
2846 for (size_t i = 0; i < expected.size(); i++) {
2847 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2848 return false;
2849 }
2850 }
2851
2852 return true;
2853}
2854
2855static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2856 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002857 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2858 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2859 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2860 if (!cert || !intermediate || !key) {
2861 return false;
2862 }
2863
2864 // Configure both client and server to accept any certificate. Add
2865 // |intermediate| to the cert store.
2866 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2867 if (!ctx ||
2868 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2869 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2870 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2871 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2872 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2873 intermediate.get())) {
2874 return false;
2875 }
2876 SSL_CTX_set_verify(
2877 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2878 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2879
2880 // By default, the client and server should each only send the leaf.
2881 bssl::UniquePtr<SSL> client, server;
2882 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2883 nullptr /* no session */)) {
2884 return false;
2885 }
2886
2887 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2888 fprintf(stderr, "Client-received chain did not match.\n");
2889 return false;
2890 }
2891
2892 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2893 fprintf(stderr, "Server-received chain did not match.\n");
2894 return false;
2895 }
2896
2897 // If auto-chaining is enabled, then the intermediate is sent.
2898 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2899 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2900 nullptr /* no session */)) {
2901 return false;
2902 }
2903
2904 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2905 {cert.get(), intermediate.get()})) {
2906 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2907 return false;
2908 }
2909
2910 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2911 {cert.get(), intermediate.get()})) {
2912 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2913 return false;
2914 }
2915
2916 // Auto-chaining does not override explicitly-configured intermediates.
2917 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2918 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2919 nullptr /* no session */)) {
2920 return false;
2921 }
2922
2923 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2924 {cert.get(), cert.get()})) {
2925 fprintf(stderr,
2926 "Client-received chain did not match (auto-chaining, explicit "
2927 "intermediate).\n");
2928 return false;
2929 }
2930
2931 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2932 {cert.get(), cert.get()})) {
2933 fprintf(stderr,
2934 "Server-received chain did not match (auto-chaining, explicit "
2935 "intermediate).\n");
2936 return false;
2937 }
2938
2939 return true;
2940}
2941
David Benjamin48063c22017-01-01 23:56:36 -05002942static bool ExpectBadWriteRetry() {
2943 int err = ERR_get_error();
2944 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2945 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2946 char buf[ERR_ERROR_STRING_BUF_LEN];
2947 ERR_error_string_n(err, buf, sizeof(buf));
2948 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2949 return false;
2950 }
2951
2952 if (ERR_peek_error() != 0) {
2953 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2954 return false;
2955 }
2956
2957 return true;
2958}
2959
2960static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
2961 uint16_t version) {
2962 if (is_dtls) {
2963 return true;
2964 }
2965
2966 for (bool enable_partial_write : std::vector<bool>{false, true}) {
2967 // Connect a client and server.
2968 bssl::UniquePtr<X509> cert = GetTestCertificate();
2969 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2970 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2971 bssl::UniquePtr<SSL> client, server;
2972 if (!cert || !key || !ctx ||
2973 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2974 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2975 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2976 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2977 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2978 nullptr /* no session */)) {
2979 return false;
2980 }
2981
2982 if (enable_partial_write) {
2983 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
2984 }
2985
2986 // Write without reading until the buffer is full and we have an unfinished
2987 // write. Keep a count so we may reread it again later. "hello!" will be
2988 // written in two chunks, "hello" and "!".
2989 char data[] = "hello!";
2990 static const int kChunkLen = 5; // The length of "hello".
2991 unsigned count = 0;
2992 for (;;) {
2993 int ret = SSL_write(client.get(), data, kChunkLen);
2994 if (ret <= 0) {
2995 int err = SSL_get_error(client.get(), ret);
2996 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
2997 break;
2998 }
2999 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
3000 return false;
3001 }
3002
3003 if (ret != 5) {
3004 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
3005 return false;
3006 }
3007
3008 count++;
3009 }
3010
3011 // Retrying with the same parameters is legal.
3012 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
3013 SSL_ERROR_WANT_WRITE) {
3014 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3015 return false;
3016 }
3017
3018 // Retrying with the same buffer but shorter length is not legal.
3019 if (SSL_get_error(client.get(),
3020 SSL_write(client.get(), data, kChunkLen - 1)) !=
3021 SSL_ERROR_SSL ||
3022 !ExpectBadWriteRetry()) {
3023 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3024 return false;
3025 }
3026
3027 // Retrying with a different buffer pointer is not legal.
3028 char data2[] = "hello";
3029 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
3030 kChunkLen)) != SSL_ERROR_SSL ||
3031 !ExpectBadWriteRetry()) {
3032 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3033 return false;
3034 }
3035
3036 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
3037 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3038 if (SSL_get_error(client.get(),
3039 SSL_write(client.get(), data2, kChunkLen)) !=
3040 SSL_ERROR_WANT_WRITE) {
3041 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3042 return false;
3043 }
3044
3045 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
3046 if (SSL_get_error(client.get(),
3047 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3048 SSL_ERROR_SSL ||
3049 !ExpectBadWriteRetry()) {
3050 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3051 return false;
3052 }
3053
3054 // Retrying with a larger buffer is legal.
3055 if (SSL_get_error(client.get(),
3056 SSL_write(client.get(), data, kChunkLen + 1)) !=
3057 SSL_ERROR_WANT_WRITE) {
3058 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3059 return false;
3060 }
3061
3062 // Drain the buffer.
3063 char buf[20];
3064 for (unsigned i = 0; i < count; i++) {
3065 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3066 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3067 fprintf(stderr, "Failed to read initial records.\n");
3068 return false;
3069 }
3070 }
3071
3072 // Now that there is space, a retry with a larger buffer should flush the
3073 // pending record, skip over that many bytes of input (on assumption they
3074 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3075 // is set, this will complete in two steps.
3076 char data3[] = "_____!";
3077 if (enable_partial_write) {
3078 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3079 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3080 fprintf(stderr, "SSL_write retry failed.\n");
3081 return false;
3082 }
3083 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3084 fprintf(stderr, "SSL_write retry failed.\n");
3085 return false;
3086 }
3087
3088 // Check the last write was correct. The data will be spread over two
3089 // records, so SSL_read returns twice.
3090 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3091 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3092 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3093 buf[0] != '!') {
3094 fprintf(stderr, "Failed to read write retry.\n");
3095 return false;
3096 }
3097 }
3098
3099 return true;
3100}
3101
David Benjamin0fef3052016-11-18 15:11:10 +09003102static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3103 const SSL_METHOD *method,
3104 uint16_t version)) {
3105 static uint16_t kTLSVersions[] = {
3106 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION,
3107 TLS1_2_VERSION, TLS1_3_VERSION,
3108 };
3109
3110 static uint16_t kDTLSVersions[] = {
3111 DTLS1_VERSION, DTLS1_2_VERSION,
3112 };
3113
David Benjamin9ef31f02016-10-31 18:01:13 -04003114 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003115 if (!test_func(false, TLS_method(), version)) {
3116 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003117 return false;
3118 }
David Benjamin0fef3052016-11-18 15:11:10 +09003119 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003120
David Benjamin0fef3052016-11-18 15:11:10 +09003121 for (uint16_t version : kDTLSVersions) {
3122 if (!test_func(true, DTLS_method(), version)) {
3123 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003124 return false;
3125 }
3126 }
3127
3128 return true;
3129}
3130
David Benjamin1d128f32015-09-08 17:41:40 -04003131int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04003132 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04003133
Adam Langley10f97f32016-07-12 08:09:33 -07003134 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003135 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003136 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3137 !TestSSL_SESSIONEncoding(kCustomSession) ||
3138 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3139 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3140 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3141 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003142 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07003143 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
3144 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
3145 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3146 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3147 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3148 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3149 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3150 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3151 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003152 // Test the padding extension at TLS 1.2.
3153 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3154 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3155 // will be no PSK binder after the padding extension.
3156 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3157 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3158 // will be a PSK binder after the padding extension.
3159 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003160 !TestClientCAList() ||
3161 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003162 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003163 !ForEachVersion(TestOneSidedShutdown) ||
Steven Valdez87eab492016-06-27 16:34:59 -04003164 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04003165 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04003166 !TestSetBIO() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003167 !ForEachVersion(TestGetPeerCertificate) ||
3168 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003169 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003170 !ForEachVersion(TestSessionIDContext) ||
3171 !ForEachVersion(TestSessionTimeout) ||
Alessandro Ghedinibf483642016-11-22 18:56:46 +00003172 !ForEachVersion(TestSessionTimeoutCertCallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003173 !ForEachVersion(TestSNICallback) ||
David Benjamin2dc02042016-09-19 19:57:37 -04003174 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04003175 !TestSetVersion() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003176 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003177 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003178 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003179 !ForEachVersion(TestAutoChain) ||
3180 !ForEachVersion(TestSSLWriteRetry)) {
Brian Smith83a82982015-04-09 16:21:10 -10003181 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04003182 return 1;
3183 }
3184
David Benjamin2e521212014-07-16 14:37:51 -04003185 printf("PASS\n");
3186 return 0;
3187}