blob: 6678b577cf1b8bdbcaebc46e15401991558a9176 [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 Benjamin96628432017-01-19 19:05:47 -050024#include <gtest/gtest.h>
25
David Benjamin751e8892014-10-19 00:59:36 -040026#include <openssl/base64.h>
27#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040028#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040029#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050032#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040033#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037
Steven Valdez87eab492016-06-27 16:34:59 -040038#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040039#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020040#include "../crypto/test/test_util.h"
41
David Benjamin721e8b72016-08-03 13:13:17 -040042#if defined(OPENSSL_WINDOWS)
43/* Windows defines struct timeval in winsock2.h. */
44OPENSSL_MSVC_PRAGMA(warning(push, 3))
45#include <winsock2.h>
46OPENSSL_MSVC_PRAGMA(warning(pop))
47#else
48#include <sys/time.h>
49#endif
50
David Benjamin1d77e562015-03-22 17:22:08 -040051
52struct ExpectedCipher {
53 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040055};
David Benjaminbb0a17c2014-09-20 15:35:39 -040056
David Benjamin1d77e562015-03-22 17:22:08 -040057struct CipherTest {
58 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040059 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050060 // The list of expected ciphers, in order.
61 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080062 // True if this cipher list should fail in strict mode.
63 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040064};
David Benjaminbb0a17c2014-09-20 15:35:39 -040065
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010066struct CurveTest {
67 // The rule string to apply.
68 const char *rule;
69 // The list of expected curves, in order.
70 std::vector<uint16_t> expected;
71};
72
David Benjaminfb974e62015-12-16 19:34:22 -050073static const CipherTest kCipherTests[] = {
74 // Selecting individual ciphers should work.
75 {
76 "ECDHE-ECDSA-CHACHA20-POLY1305:"
77 "ECDHE-RSA-CHACHA20-POLY1305:"
78 "ECDHE-ECDSA-AES128-GCM-SHA256:"
79 "ECDHE-RSA-AES128-GCM-SHA256",
80 {
81 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050082 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050083 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
84 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
85 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080086 false,
David Benjaminfb974e62015-12-16 19:34:22 -050087 },
88 // + reorders selected ciphers to the end, keeping their relative order.
89 {
90 "ECDHE-ECDSA-CHACHA20-POLY1305:"
91 "ECDHE-RSA-CHACHA20-POLY1305:"
92 "ECDHE-ECDSA-AES128-GCM-SHA256:"
93 "ECDHE-RSA-AES128-GCM-SHA256:"
94 "+aRSA",
95 {
96 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050097 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
98 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050099 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
100 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800101 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500102 },
103 // ! banishes ciphers from future selections.
104 {
105 "!aRSA:"
106 "ECDHE-ECDSA-CHACHA20-POLY1305:"
107 "ECDHE-RSA-CHACHA20-POLY1305:"
108 "ECDHE-ECDSA-AES128-GCM-SHA256:"
109 "ECDHE-RSA-AES128-GCM-SHA256",
110 {
111 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500112 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
113 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800114 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500115 },
116 // Multiple masks can be ANDed in a single rule.
117 {
118 "kRSA+AESGCM+AES128",
119 {
120 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
121 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800122 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500123 },
124 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700125 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500126 // ECDHE_RSA.
127 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700128 "ALL:-kECDHE:"
129#ifdef BORINGSSL_ENABLE_DHE_TLS
130 "-kDHE:"
131#endif
132 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500133 "AESGCM+AES128+aRSA",
134 {
135 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700136#ifdef BORINGSSL_ENABLE_DHE_TLS
David Benjaminfb974e62015-12-16 19:34:22 -0500137 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700138#endif
David Benjaminfb974e62015-12-16 19:34:22 -0500139 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
140 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800141 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500142 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800143 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500144 {
145 "ECDHE-ECDSA-CHACHA20-POLY1305:"
146 "ECDHE-RSA-CHACHA20-POLY1305:"
147 "ECDHE-ECDSA-AES128-GCM-SHA256:"
148 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800149 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500150 {
151 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500152 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500153 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
154 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
155 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800156 true,
157 },
158 // Unknown selectors are no-ops, except in strict mode.
159 {
160 "ECDHE-ECDSA-CHACHA20-POLY1305:"
161 "ECDHE-RSA-CHACHA20-POLY1305:"
162 "ECDHE-ECDSA-AES128-GCM-SHA256:"
163 "ECDHE-RSA-AES128-GCM-SHA256:"
164 "-BOGUS2:+BOGUS3:!BOGUS4",
165 {
166 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
167 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
168 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
169 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
170 },
171 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500172 },
173 // Square brackets specify equi-preference groups.
174 {
175 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
176 "[ECDHE-RSA-CHACHA20-POLY1305]:"
177 "ECDHE-RSA-AES128-GCM-SHA256",
178 {
179 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500180 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800181 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500182 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
183 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800184 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500185 },
186 // @STRENGTH performs a stable strength-sort of the selected ciphers and
187 // only the selected ciphers.
188 {
189 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700190 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700191#ifdef BORINGSSL_ENABLE_DHE_TLS
192 "!kEDH:"
193#endif
194 "!AESGCM:!3DES:!SHA256:!SHA384:"
David Benjaminfb974e62015-12-16 19:34:22 -0500195 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700196 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500197 // Select ECDHE ones and sort them by strength. Ties should resolve
198 // based on the order above.
199 "kECDHE:@STRENGTH:-ALL:"
200 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
201 // by strength. Then RSA, backwards by strength.
202 "aRSA",
203 {
204 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
205 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500206 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500207 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
208 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
209 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800210 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500211 },
212 // Exact ciphers may not be used in multi-part rules; they are treated
213 // as unknown aliases.
214 {
215 "ECDHE-ECDSA-AES128-GCM-SHA256:"
216 "ECDHE-RSA-AES128-GCM-SHA256:"
217 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
218 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
219 {
220 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
222 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800223 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500224 },
225 // SSLv3 matches everything that existed before TLS 1.2.
226 {
227 "AES128-SHA:AES128-SHA256:!SSLv3",
228 {
229 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
230 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800231 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500232 },
233 // TLSv1.2 matches everything added in TLS 1.2.
234 {
235 "AES128-SHA:AES128-SHA256:!TLSv1.2",
236 {
237 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
238 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800239 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500240 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800241 // The two directives have no intersection. But each component is valid, so
242 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500243 {
244 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
245 {
246 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
247 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
248 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800249 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500250 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400251};
252
253static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400254 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400255 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
256 "RSA]",
257 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400258 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400259 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400260 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400261 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400262 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400263 "",
264 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400265 // COMPLEMENTOFDEFAULT is empty.
266 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400267 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400268 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400269 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400270 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
271 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
272 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
273 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700274 // Opcode supplied, but missing selector.
275 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400276};
277
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700278static const char *kMustNotIncludeNull[] = {
279 "ALL",
280 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500281 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700282 "FIPS",
283 "SHA",
284 "SHA1",
285 "RSA",
286 "SSLv3",
287 "TLSv1",
288 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700289};
290
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100291static const CurveTest kCurveTests[] = {
292 {
293 "P-256",
294 { SSL_CURVE_SECP256R1 },
295 },
296 {
297 "P-256:P-384:P-521:X25519",
298 {
299 SSL_CURVE_SECP256R1,
300 SSL_CURVE_SECP384R1,
301 SSL_CURVE_SECP521R1,
302 SSL_CURVE_X25519,
303 },
304 },
305};
306
307static const char *kBadCurvesLists[] = {
308 "",
309 ":",
310 "::",
311 "P-256::X25519",
312 "RSA:P-256",
313 "P-256:RSA",
314 "X25519:P-256:",
315 ":X25519:P-256",
316};
317
David Benjamin1d77e562015-03-22 17:22:08 -0400318static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
319 bool in_group = false;
320 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400321 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
322 if (!in_group && list->in_group_flags[i]) {
323 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400324 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400325 }
326 fprintf(stderr, "\t");
327 if (in_group) {
328 fprintf(stderr, " ");
329 }
330 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
331 if (in_group && !list->in_group_flags[i]) {
332 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400333 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400334 }
335 }
336}
337
David Benjaminfb974e62015-12-16 19:34:22 -0500338static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700339 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400340 if (!ctx) {
341 return false;
David Benjamin65226252015-02-05 16:49:47 -0500342 }
343
David Benjaminfb974e62015-12-16 19:34:22 -0500344 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
345 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400346 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400347 }
348
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800349 if (!SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule) != t.strict_fail) {
350 fprintf(stderr, "Unexpected strict failure result testing cipher rule '%s':"
351 " expected %d\n", t.rule, t.strict_fail);
352 return false;
353 }
354
David Benjamin1d77e562015-03-22 17:22:08 -0400355 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500356 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
357 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
358 PrintCipherPreferenceList(ctx->cipher_list);
359 return false;
360 }
361
362 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400363 const SSL_CIPHER *cipher =
364 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500365 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
366 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
367 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400368 PrintCipherPreferenceList(ctx->cipher_list);
369 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400370 }
371 }
372
David Benjamin1d77e562015-03-22 17:22:08 -0400373 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400374}
375
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700376static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700377 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700378 if (!ctx) {
379 return false;
380 }
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800381 if (!SSL_CTX_set_strict_cipher_list(ctx.get(), rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700382 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
383 return false;
384 }
385 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
386 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
387 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
388 return false;
389 }
390 }
391 return true;
392}
393
David Benjamin1d77e562015-03-22 17:22:08 -0400394static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500395 for (const CipherTest &test : kCipherTests) {
396 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400397 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400398 }
399 }
400
David Benjaminfb974e62015-12-16 19:34:22 -0500401 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700402 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400403 if (!ctx) {
404 return false;
David Benjamin65226252015-02-05 16:49:47 -0500405 }
David Benjaminfb974e62015-12-16 19:34:22 -0500406 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
407 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400408 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400409 }
410 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400411 }
412
David Benjaminfb974e62015-12-16 19:34:22 -0500413 for (const char *rule : kMustNotIncludeNull) {
414 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700415 return false;
416 }
417 }
418
David Benjamin1d77e562015-03-22 17:22:08 -0400419 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400420}
David Benjamin2e521212014-07-16 14:37:51 -0400421
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100422static bool TestCurveRule(const CurveTest &t) {
423 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
424 if (!ctx) {
425 return false;
426 }
427
428 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
429 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
430 return false;
431 }
432
433 // Compare the two lists.
434 if (ctx->supported_group_list_len != t.expected.size()) {
435 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
436 return false;
437 }
438
439 for (size_t i = 0; i < t.expected.size(); i++) {
440 if (t.expected[i] != ctx->supported_group_list[i]) {
441 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
442 return false;
443 }
444 }
445
446 return true;
447}
448
449static bool TestCurveRules() {
450 for (const CurveTest &test : kCurveTests) {
451 if (!TestCurveRule(test)) {
452 return false;
453 }
454 }
455
456 for (const char *rule : kBadCurvesLists) {
457 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
458 if (!ctx) {
459 return false;
460 }
461 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
462 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
463 return false;
464 }
465 ERR_clear_error();
466 }
467
468 return true;
469}
470
Adam Langley364f7a62016-12-12 10:51:00 -0800471// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700472static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800473 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700474 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
475 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
476 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
477 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
478 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
479 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
480 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
481 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
482 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
483 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
484 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
485 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
486 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
487 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
488 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
489 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
490 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
491 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
492 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
493 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
494 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
495 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
496 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
497 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
498 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
499 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
500 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
501 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
502 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800503 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700504
505// kCustomSession is a custom serialized SSL_SESSION generated by
506// filling in missing fields from |kOpenSSLSession|. This includes
507// providing |peer_sha256|, so |peer| is not serialized.
508static const char kCustomSession[] =
509 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
510 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
511 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
512 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
513 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
514 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
515 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
516 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
517
518// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
519static const char kBoringSSLSession[] =
520 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
521 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
522 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
523 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
524 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
525 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
526 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
527 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
528 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
529 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
530 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
531 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
532 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
533 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
534 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
535 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
536 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
537 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
538 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
539 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
540 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
541 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
542 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
543 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
544 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
545 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
546 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
547 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
548 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
549 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
550 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
551 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
552 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
553 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
554 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
555 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
556 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
557 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
558 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
559 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
560 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
561 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
562 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
563 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
564 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
565 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
566 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
567 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
568 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
569 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
570 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
571 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
572 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
573 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
574 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
575 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
576 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
577 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
578 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
579 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
580 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
581 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
582 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
583 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
584 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
585 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
586 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
587 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
588 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
589 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
590 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
591 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
592 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
593 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
594 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
595 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
596 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
597 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
598 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
599 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
600 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
601 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
602 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
603 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
604 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
605 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
606 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
607 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
608 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
609 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
610 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
611 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
612 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
613 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
614 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
615
616// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
617// the final (optional) element of |kCustomSession| with tag number 30.
618static const char kBadSessionExtraField[] =
619 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
620 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
621 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
622 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
623 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
624 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
625 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
626 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
627
628// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
629// the version of |kCustomSession| with 2.
630static const char kBadSessionVersion[] =
631 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
632 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
633 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
634 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
635 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
636 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
637 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
638 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
639
640// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
641// appended.
642static const char kBadSessionTrailingData[] =
643 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
644 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
645 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
646 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
647 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
648 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
649 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
650 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
651
David Benjamin1d77e562015-03-22 17:22:08 -0400652static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400653 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400654 if (!EVP_DecodedLength(&len, strlen(in))) {
655 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400656 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400657 }
658
David Benjamin1d77e562015-03-22 17:22:08 -0400659 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800660 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400661 strlen(in))) {
662 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400663 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400664 }
David Benjamin1d77e562015-03-22 17:22:08 -0400665 out->resize(len);
666 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400667}
668
David Benjamin1d77e562015-03-22 17:22:08 -0400669static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400670 const uint8_t *cptr;
671 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400672
David Benjamin1d77e562015-03-22 17:22:08 -0400673 // Decode the input.
674 std::vector<uint8_t> input;
675 if (!DecodeBase64(&input, input_b64)) {
676 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400677 }
678
David Benjamin1d77e562015-03-22 17:22:08 -0400679 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800680 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
681 if (!ssl_ctx) {
682 return false;
683 }
684 bssl::UniquePtr<SSL_SESSION> session(
685 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400686 if (!session) {
687 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400688 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400689 }
690
David Benjamin1d77e562015-03-22 17:22:08 -0400691 // Verify the SSL_SESSION encoding round-trips.
692 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700693 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400694 uint8_t *encoded_raw;
695 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400696 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400697 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400698 }
David Benjamin1d77e562015-03-22 17:22:08 -0400699 encoded.reset(encoded_raw);
700 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500701 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400702 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200703 hexdump(stderr, "Before: ", input.data(), input.size());
704 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400705 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400706 }
David Benjamin3cac4502014-10-21 01:46:30 -0400707
David Benjaminfd67aa82015-06-15 19:41:48 -0400708 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800709 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400710 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800711 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400712 fprintf(stderr, "d2i_SSL_SESSION failed\n");
713 return false;
714 }
715
David Benjamin1d77e562015-03-22 17:22:08 -0400716 // Verify the SSL_SESSION encoding round-trips via the legacy API.
717 int len = i2d_SSL_SESSION(session.get(), NULL);
718 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400719 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400720 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400721 }
722
David Benjamin1d77e562015-03-22 17:22:08 -0400723 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
724 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400725 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400726 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400727 }
David Benjamin1d77e562015-03-22 17:22:08 -0400728
729 ptr = encoded.get();
730 len = i2d_SSL_SESSION(session.get(), &ptr);
731 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400732 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400733 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400734 }
David Benjamin1d77e562015-03-22 17:22:08 -0400735 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400736 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400737 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400738 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500739 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400740 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400741 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400742 }
743
David Benjamin1d77e562015-03-22 17:22:08 -0400744 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400745}
746
David Benjaminf297e022015-05-28 19:55:29 -0400747static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
748 std::vector<uint8_t> input;
749 if (!DecodeBase64(&input, input_b64)) {
750 return false;
751 }
752
753 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800754 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
755 if (!ssl_ctx) {
756 return false;
757 }
758 bssl::UniquePtr<SSL_SESSION> session(
759 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400760 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400761 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400762 return false;
763 }
764 ERR_clear_error();
765 return true;
766}
767
David Benjamin10e664b2016-06-20 22:20:47 -0400768static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400769 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700770 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400771 if (!ctx) {
772 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500773 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400774 if (ctx->min_version != min_version || ctx->max_version != max_version) {
775 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
776 ctx->min_version, ctx->max_version, min_version, max_version);
777 return false;
778 }
779 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500780}
781
David Benjamin1d77e562015-03-22 17:22:08 -0400782static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500783 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
784 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400785 return false;
David Benjamin65226252015-02-05 16:49:47 -0500786 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700787 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400788 if (!rfc_name) {
789 return false;
790 }
David Benjamin67be0482015-04-20 16:19:00 -0400791 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400792 return true;
David Benjamin65226252015-02-05 16:49:47 -0500793}
794
795typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500796 int id;
David Benjamin65226252015-02-05 16:49:47 -0500797 const char *rfc_name;
798} CIPHER_RFC_NAME_TEST;
799
800static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400801 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
802 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700803#ifdef BORINGSSL_ENABLE_DHE_TLS
Steven Valdez803c77a2016-09-06 14:13:43 -0400804 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
805 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
806 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700807#endif
Steven Valdez803c77a2016-09-06 14:13:43 -0400808 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
809 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
810 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
811 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
812 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
813 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
814 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
815 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
816 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
817 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
818 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
819 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
820 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
821 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
822 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
823 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
824 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500825};
826
David Benjamin1d77e562015-03-22 17:22:08 -0400827static bool TestCipherGetRFCName(void) {
828 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400829 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500830 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400831 std::string rfc_name;
832 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
833 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
834 return false;
David Benjamin65226252015-02-05 16:49:47 -0500835 }
David Benjamin1d77e562015-03-22 17:22:08 -0400836 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500837 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400838 rfc_name.c_str(), test->rfc_name);
839 return false;
David Benjamin65226252015-02-05 16:49:47 -0500840 }
David Benjamin65226252015-02-05 16:49:47 -0500841 }
David Benjamin1d77e562015-03-22 17:22:08 -0400842 return true;
David Benjamin65226252015-02-05 16:49:47 -0500843}
844
Steven Valdeza833c352016-11-01 13:39:36 -0400845// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
846// version and ticket length or nullptr on failure.
847static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
848 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400849 std::vector<uint8_t> der;
850 if (!DecodeBase64(&der, kOpenSSLSession)) {
851 return nullptr;
852 }
Adam Langley46db7af2017-02-01 15:49:37 -0800853
854 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
855 if (!ssl_ctx) {
856 return nullptr;
857 }
Steven Valdeza833c352016-11-01 13:39:36 -0400858 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800859 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400860 if (!session) {
861 return nullptr;
862 }
863
Steven Valdeza833c352016-11-01 13:39:36 -0400864 session->ssl_version = version;
865
David Benjamin422fe082015-07-21 22:03:43 -0400866 // Swap out the ticket for a garbage one.
867 OPENSSL_free(session->tlsext_tick);
868 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
869 if (session->tlsext_tick == nullptr) {
870 return nullptr;
871 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500872 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400873 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400874
875 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500876#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
877 session->time = 1234;
878#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400879 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500880#endif
David Benjamin422fe082015-07-21 22:03:43 -0400881 return session;
882}
883
David Benjaminafc64de2016-07-19 17:12:41 +0200884static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700885 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200886 if (!bio) {
887 return false;
888 }
889 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400890 BIO_up_ref(bio.get());
891 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200892 int ret = SSL_connect(ssl);
893 if (ret > 0) {
894 // SSL_connect should fail without a BIO to write to.
895 return false;
896 }
897 ERR_clear_error();
898
899 const uint8_t *client_hello;
900 size_t client_hello_len;
901 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
902 return false;
903 }
904 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
905 return true;
906}
907
Steven Valdeza833c352016-11-01 13:39:36 -0400908// GetClientHelloLen creates a client SSL connection with the specified version
909// and ticket length. It returns the length of the ClientHello, not including
910// the record header, on success and zero on error.
911static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
912 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700913 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400914 bssl::UniquePtr<SSL_SESSION> session =
915 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400916 if (!ctx || !session) {
917 return 0;
918 }
Steven Valdeza833c352016-11-01 13:39:36 -0400919
920 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700921 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400922 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800923 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -0400924 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400925 return 0;
926 }
Steven Valdeza833c352016-11-01 13:39:36 -0400927
David Benjaminafc64de2016-07-19 17:12:41 +0200928 std::vector<uint8_t> client_hello;
929 if (!GetClientHello(ssl.get(), &client_hello) ||
930 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400931 return 0;
932 }
Steven Valdeza833c352016-11-01 13:39:36 -0400933
David Benjaminafc64de2016-07-19 17:12:41 +0200934 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400935}
936
937struct PaddingTest {
938 size_t input_len, padded_len;
939};
940
941static const PaddingTest kPaddingTests[] = {
942 // ClientHellos of length below 0x100 do not require padding.
943 {0xfe, 0xfe},
944 {0xff, 0xff},
945 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
946 {0x100, 0x200},
947 {0x123, 0x200},
948 {0x1fb, 0x200},
949 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
950 // padding extension takes a minimum of four bytes plus one required content
951 // byte. (To work around yet more server bugs, we avoid empty final
952 // extensions.)
953 {0x1fc, 0x201},
954 {0x1fd, 0x202},
955 {0x1fe, 0x203},
956 {0x1ff, 0x204},
957 // Finally, larger ClientHellos need no padding.
958 {0x200, 0x200},
959 {0x201, 0x201},
960};
961
Steven Valdeza833c352016-11-01 13:39:36 -0400962static bool TestPaddingExtension(uint16_t max_version,
963 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400964 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400965 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400966 if (base_len == 0) {
967 return false;
968 }
969
970 for (const PaddingTest &test : kPaddingTests) {
971 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400972 fprintf(stderr,
973 "Baseline ClientHello too long (max_version = %04x, "
974 "session_version = %04x).\n",
975 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400976 return false;
977 }
978
Steven Valdeza833c352016-11-01 13:39:36 -0400979 size_t padded_len = GetClientHelloLen(max_version, session_version,
980 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400981 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400982 fprintf(stderr,
983 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
984 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400985 static_cast<unsigned>(test.input_len),
986 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400987 static_cast<unsigned>(test.padded_len), max_version,
988 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400989 return false;
990 }
991 }
Steven Valdeza833c352016-11-01 13:39:36 -0400992
David Benjamin422fe082015-07-21 22:03:43 -0400993 return true;
994}
995
David Benjamin1d128f32015-09-08 17:41:40 -0400996// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
997// before configuring as a server.
David Benjaminf0d8e222017-02-04 10:58:26 -0500998TEST(SSLTest, ClientCAList) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700999 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001000 ASSERT_TRUE(ctx);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001001 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001002 ASSERT_TRUE(ssl);
David Benjamin1d128f32015-09-08 17:41:40 -04001003
Adam Langley34b4c822017-02-02 10:57:17 -08001004 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1005 ASSERT_TRUE(name);
David Benjamin1d128f32015-09-08 17:41:40 -04001006
Adam Langley34b4c822017-02-02 10:57:17 -08001007 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1008 ASSERT_TRUE(name_dup);
1009
1010 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1011 ASSERT_TRUE(stack);
1012
1013 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1014 name_dup.release();
1015
1016 // |SSL_set_client_CA_list| takes ownership.
1017 SSL_set_client_CA_list(ssl.get(), stack.release());
1018
1019 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1020 ASSERT_TRUE(result);
1021 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1022 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
David Benjamin1d128f32015-09-08 17:41:40 -04001023}
1024
David Benjamin0f653952015-10-18 14:28:01 -04001025static void AppendSession(SSL_SESSION *session, void *arg) {
1026 std::vector<SSL_SESSION*> *out =
1027 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1028 out->push_back(session);
1029}
1030
1031// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1032// order.
1033static bool ExpectCache(SSL_CTX *ctx,
1034 const std::vector<SSL_SESSION*> &expected) {
1035 // Check the linked list.
1036 SSL_SESSION *ptr = ctx->session_cache_head;
1037 for (SSL_SESSION *session : expected) {
1038 if (ptr != session) {
1039 return false;
1040 }
1041 // TODO(davidben): This is an absurd way to denote the end of the list.
1042 if (ptr->next ==
1043 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1044 ptr = nullptr;
1045 } else {
1046 ptr = ptr->next;
1047 }
1048 }
1049 if (ptr != nullptr) {
1050 return false;
1051 }
1052
1053 // Check the hash table.
1054 std::vector<SSL_SESSION*> actual, expected_copy;
1055 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1056 expected_copy = expected;
1057
1058 std::sort(actual.begin(), actual.end());
1059 std::sort(expected_copy.begin(), expected_copy.end());
1060
1061 return actual == expected_copy;
1062}
1063
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001064static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
Adam Langley46db7af2017-02-01 15:49:37 -08001065 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1066 if (!ssl_ctx) {
1067 return nullptr;
1068 }
1069 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
David Benjamin0f653952015-10-18 14:28:01 -04001070 if (!ret) {
1071 return nullptr;
1072 }
1073
1074 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001075 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1076 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001077 return ret;
1078}
1079
David Benjamin0f653952015-10-18 14:28:01 -04001080// Test that the internal session cache behaves as expected.
1081static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001082 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001083 if (!ctx) {
1084 return false;
1085 }
1086
1087 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001088 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001089 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001090 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001091 if (!session) {
1092 return false;
1093 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001094 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001095 }
1096
1097 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1098
1099 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001100 for (const auto &session : sessions) {
1101 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001102 return false;
1103 }
1104 }
1105
1106 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001107 std::vector<SSL_SESSION*> expected = {
1108 sessions[9].get(),
1109 sessions[8].get(),
1110 sessions[7].get(),
1111 sessions[6].get(),
1112 sessions[5].get(),
1113 };
David Benjamin0f653952015-10-18 14:28:01 -04001114 if (!ExpectCache(ctx.get(), expected)) {
1115 return false;
1116 }
1117
1118 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001119 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001120 !ExpectCache(ctx.get(), expected)) {
1121 return false;
1122 }
1123
1124 // Although collisions should be impossible (256-bit session IDs), the cache
1125 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001126 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001127 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1128 return false;
1129 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001130 expected = {
1131 collision.get(),
1132 sessions[9].get(),
1133 sessions[8].get(),
1134 sessions[6].get(),
1135 sessions[5].get(),
1136 };
David Benjamin0f653952015-10-18 14:28:01 -04001137 if (!ExpectCache(ctx.get(), expected)) {
1138 return false;
1139 }
1140
1141 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001142 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001143 return false;
1144 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001145 expected = {
1146 collision.get(),
1147 sessions[9].get(),
1148 sessions[8].get(),
1149 sessions[5].get(),
1150 };
David Benjamin0f653952015-10-18 14:28:01 -04001151 if (!ExpectCache(ctx.get(), expected)) {
1152 return false;
1153 }
1154
1155 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001156 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1157 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001158 !ExpectCache(ctx.get(), expected)) {
1159 return false;
1160 }
1161
1162 return true;
1163}
1164
David Benjaminde942382016-02-11 12:02:01 -05001165static uint16_t EpochFromSequence(uint64_t seq) {
1166 return static_cast<uint16_t>(seq >> 48);
1167}
1168
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001169static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001170 static const char kCertPEM[] =
1171 "-----BEGIN CERTIFICATE-----\n"
1172 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1173 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1174 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1175 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1176 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1177 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1178 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1179 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1180 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1181 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1182 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1183 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1184 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1185 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001186 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001187 return bssl::UniquePtr<X509>(
1188 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001189}
1190
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001191static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001192 static const char kKeyPEM[] =
1193 "-----BEGIN RSA PRIVATE KEY-----\n"
1194 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1195 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1196 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1197 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1198 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1199 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1200 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1201 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1202 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1203 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1204 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1205 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1206 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1207 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001208 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1209 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001210 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1211}
1212
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001213static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001214 static const char kCertPEM[] =
1215 "-----BEGIN CERTIFICATE-----\n"
1216 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1217 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1218 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1219 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1220 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1221 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1222 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1223 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1224 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1225 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1226 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001227 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1228 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001229}
1230
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001231static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001232 static const char kKeyPEM[] =
1233 "-----BEGIN PRIVATE KEY-----\n"
1234 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1235 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1236 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1237 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001238 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1239 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001240 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1241}
1242
Adam Langleyd04ca952017-02-28 11:26:51 -08001243static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1244 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1245 char *name, *header;
1246 uint8_t *data;
1247 long data_len;
1248 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1249 &data_len)) {
1250 return nullptr;
1251 }
1252 OPENSSL_free(name);
1253 OPENSSL_free(header);
1254
1255 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1256 CRYPTO_BUFFER_new(data, data_len, nullptr));
1257 OPENSSL_free(data);
1258 return ret;
1259}
1260
1261static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001262 static const char kCertPEM[] =
1263 "-----BEGIN CERTIFICATE-----\n"
1264 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1265 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1266 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1267 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1268 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1269 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1270 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1271 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1272 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1273 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1274 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1275 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1276 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1277 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1278 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1279 "1ngWZ7Ih\n"
1280 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001281 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001282}
1283
Adam Langleyd04ca952017-02-28 11:26:51 -08001284static bssl::UniquePtr<X509> X509FromBuffer(
1285 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1286 if (!buffer) {
1287 return nullptr;
1288 }
1289 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1290 return bssl::UniquePtr<X509>(
1291 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1292}
1293
1294static bssl::UniquePtr<X509> GetChainTestCertificate() {
1295 return X509FromBuffer(GetChainTestCertificateBuffer());
1296}
1297
1298static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001299 static const char kCertPEM[] =
1300 "-----BEGIN CERTIFICATE-----\n"
1301 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1302 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1303 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1304 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1305 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1306 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1307 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1308 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1309 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1310 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1311 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1312 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1313 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1314 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1315 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1316 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001317 return BufferFromPEM(kCertPEM);
1318}
1319
1320static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1321 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001322}
1323
1324static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1325 static const char kKeyPEM[] =
1326 "-----BEGIN PRIVATE KEY-----\n"
1327 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1328 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1329 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1330 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1331 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1332 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1333 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1334 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1335 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1336 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1337 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1338 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1339 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1340 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1341 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1342 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1343 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1344 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1345 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1346 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1347 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1348 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1349 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1350 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1351 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1352 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1353 "-----END PRIVATE KEY-----\n";
1354 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1355 return bssl::UniquePtr<EVP_PKEY>(
1356 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1357}
1358
David Benjaminb79cc842016-12-07 15:57:14 -05001359static bool CompleteHandshakes(SSL *client, SSL *server) {
1360 // Drive both their handshakes to completion.
1361 for (;;) {
1362 int client_ret = SSL_do_handshake(client);
1363 int client_err = SSL_get_error(client, client_ret);
1364 if (client_err != SSL_ERROR_NONE &&
1365 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001366 client_err != SSL_ERROR_WANT_WRITE &&
1367 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001368 fprintf(stderr, "Client error: %d\n", client_err);
1369 return false;
1370 }
1371
1372 int server_ret = SSL_do_handshake(server);
1373 int server_err = SSL_get_error(server, server_ret);
1374 if (server_err != SSL_ERROR_NONE &&
1375 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001376 server_err != SSL_ERROR_WANT_WRITE &&
1377 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001378 fprintf(stderr, "Server error: %d\n", server_err);
1379 return false;
1380 }
1381
1382 if (client_ret == 1 && server_ret == 1) {
1383 break;
1384 }
1385 }
1386
1387 return true;
1388}
1389
1390static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1391 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001392 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1393 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001394 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001395 if (!client || !server) {
1396 return false;
1397 }
1398 SSL_set_connect_state(client.get());
1399 SSL_set_accept_state(server.get());
1400
David Benjamina20e5352016-08-02 19:09:41 -04001401 SSL_set_session(client.get(), session);
1402
David Benjaminde942382016-02-11 12:02:01 -05001403 BIO *bio1, *bio2;
1404 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1405 return false;
1406 }
1407 // SSL_set_bio takes ownership.
1408 SSL_set_bio(client.get(), bio1, bio1);
1409 SSL_set_bio(server.get(), bio2, bio2);
1410
David Benjaminb79cc842016-12-07 15:57:14 -05001411 if (!CompleteHandshakes(client.get(), server.get())) {
1412 return false;
David Benjaminde942382016-02-11 12:02:01 -05001413 }
1414
David Benjamin686bb192016-05-10 15:15:41 -04001415 *out_client = std::move(client);
1416 *out_server = std::move(server);
1417 return true;
1418}
1419
David Benjamin0fef3052016-11-18 15:11:10 +09001420static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1421 uint16_t version) {
1422 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1423 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1424 if (!server_ctx || !client_ctx ||
1425 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1426 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1427 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1428 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1429 return false;
1430 }
David Benjamin686bb192016-05-10 15:15:41 -04001431
David Benjamin0fef3052016-11-18 15:11:10 +09001432 bssl::UniquePtr<X509> cert = GetTestCertificate();
1433 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1434 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1435 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1436 return false;
1437 }
David Benjamin686bb192016-05-10 15:15:41 -04001438
David Benjamin0fef3052016-11-18 15:11:10 +09001439 bssl::UniquePtr<SSL> client, server;
1440 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1441 server_ctx.get(), nullptr /* no session */)) {
1442 return false;
1443 }
David Benjamin686bb192016-05-10 15:15:41 -04001444
David Benjamin0fef3052016-11-18 15:11:10 +09001445 // Drain any post-handshake messages to ensure there are no unread records
1446 // on either end.
1447 uint8_t byte = 0;
1448 if (SSL_read(client.get(), &byte, 1) > 0 ||
1449 SSL_read(server.get(), &byte, 1) > 0) {
1450 fprintf(stderr, "Received unexpected data.\n");
1451 return false;
1452 }
David Benjaminde942382016-02-11 12:02:01 -05001453
David Benjamin0fef3052016-11-18 15:11:10 +09001454 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1455 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1456 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1457 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001458
David Benjamin0fef3052016-11-18 15:11:10 +09001459 if (is_dtls) {
1460 // Both client and server must be at epoch 1.
1461 if (EpochFromSequence(client_read_seq) != 1 ||
1462 EpochFromSequence(client_write_seq) != 1 ||
1463 EpochFromSequence(server_read_seq) != 1 ||
1464 EpochFromSequence(server_write_seq) != 1) {
1465 fprintf(stderr, "Bad epochs.\n");
1466 return false;
David Benjaminde942382016-02-11 12:02:01 -05001467 }
David Benjamin0fef3052016-11-18 15:11:10 +09001468
1469 // The next record to be written should exceed the largest received.
1470 if (client_write_seq <= server_read_seq ||
1471 server_write_seq <= client_read_seq) {
1472 fprintf(stderr, "Inconsistent sequence numbers.\n");
1473 return false;
1474 }
1475 } else {
1476 // The next record to be written should equal the next to be received.
1477 if (client_write_seq != server_read_seq ||
1478 server_write_seq != client_read_seq) {
1479 fprintf(stderr, "Inconsistent sequence numbers.\n");
1480 return false;
1481 }
1482 }
1483
1484 // Send a record from client to server.
1485 if (SSL_write(client.get(), &byte, 1) != 1 ||
1486 SSL_read(server.get(), &byte, 1) != 1) {
1487 fprintf(stderr, "Could not send byte.\n");
1488 return false;
1489 }
1490
1491 // The client write and server read sequence numbers should have
1492 // incremented.
1493 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1494 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1495 fprintf(stderr, "Sequence numbers did not increment.\n");
1496 return false;
David Benjaminde942382016-02-11 12:02:01 -05001497 }
1498
1499 return true;
1500}
1501
David Benjamin68f37b72016-11-18 15:14:42 +09001502static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1503 uint16_t version) {
1504 // SSL_shutdown is a no-op in DTLS.
1505 if (is_dtls) {
1506 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001507 }
1508
David Benjamin68f37b72016-11-18 15:14:42 +09001509 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1510 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001511 bssl::UniquePtr<X509> cert = GetTestCertificate();
1512 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001513 if (!client_ctx || !server_ctx || !cert || !key ||
1514 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1515 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1516 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1517 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001518 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1519 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1520 return false;
1521 }
1522
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001523 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001524 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001525 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001526 return false;
1527 }
1528
1529 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1530 // one side has shut down.
1531 if (SSL_shutdown(client.get()) != 0) {
1532 fprintf(stderr, "Could not shutdown.\n");
1533 return false;
1534 }
1535
1536 // Reading from the server should consume the EOF.
1537 uint8_t byte;
1538 if (SSL_read(server.get(), &byte, 1) != 0 ||
1539 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1540 fprintf(stderr, "Connection was not shut down cleanly.\n");
1541 return false;
1542 }
1543
1544 // However, the server may continue to write data and then shut down the
1545 // connection.
1546 byte = 42;
1547 if (SSL_write(server.get(), &byte, 1) != 1 ||
1548 SSL_read(client.get(), &byte, 1) != 1 ||
1549 byte != 42) {
1550 fprintf(stderr, "Could not send byte.\n");
1551 return false;
1552 }
1553
1554 // The server may then shutdown the connection.
1555 if (SSL_shutdown(server.get()) != 1 ||
1556 SSL_shutdown(client.get()) != 1) {
1557 fprintf(stderr, "Could not complete shutdown.\n");
1558 return false;
1559 }
1560
1561 return true;
1562}
David Benjamin68f37b72016-11-18 15:14:42 +09001563
David Benjaminf0d8e222017-02-04 10:58:26 -05001564TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001565 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1566 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001567 ASSERT_TRUE(client_ctx);
1568 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001569
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001570 bssl::UniquePtr<X509> cert = GetTestCertificate();
1571 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001572 ASSERT_TRUE(cert);
1573 ASSERT_TRUE(key);
1574 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1575 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001576
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001577 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001578 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
1579 server_ctx.get(),
1580 nullptr /* no session */));
Steven Valdez87eab492016-06-27 16:34:59 -04001581
1582 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjaminf0d8e222017-02-04 10:58:26 -05001583 bssl::UniquePtr<SSL_SESSION> session1(
1584 SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
1585 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001586
Steven Valdez84b5c002016-08-25 16:30:58 -04001587 session1->not_resumable = 0;
1588
Steven Valdez87eab492016-06-27 16:34:59 -04001589 uint8_t *s0_bytes, *s1_bytes;
1590 size_t s0_len, s1_len;
1591
David Benjaminf0d8e222017-02-04 10:58:26 -05001592 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001593 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001594
David Benjaminf0d8e222017-02-04 10:58:26 -05001595 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001596 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001597
David Benjamin7d7554b2017-02-04 11:48:59 -05001598 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001599}
David Benjamin686bb192016-05-10 15:15:41 -04001600
David Benjaminf0d8e222017-02-04 10:58:26 -05001601static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1602 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1603 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001604
1605 // The wrapper BIOs are always equal when fds are equal, even if set
1606 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001607 if (rfd == wfd) {
1608 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001609 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001610}
1611
David Benjaminf0d8e222017-02-04 10:58:26 -05001612TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001613 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001614 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001615
1616 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001617 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001618 ASSERT_TRUE(ssl);
1619 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1620 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1621 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001622
1623 // Test setting the same FD.
1624 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001625 ASSERT_TRUE(ssl);
1626 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1627 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001628
1629 // Test setting the same FD one side at a time.
1630 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001631 ASSERT_TRUE(ssl);
1632 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1633 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1634 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001635
1636 // Test setting the same FD in the other order.
1637 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001638 ASSERT_TRUE(ssl);
1639 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1640 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1641 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001642
David Benjamin5c0fb882016-06-14 14:03:51 -04001643 // Test changing the read FD partway through.
1644 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001645 ASSERT_TRUE(ssl);
1646 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1647 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1648 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001649
1650 // Test changing the write FD partway through.
1651 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001652 ASSERT_TRUE(ssl);
1653 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1654 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1655 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001656
1657 // Test a no-op change to the read FD partway through.
1658 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001659 ASSERT_TRUE(ssl);
1660 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1661 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1662 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001663
1664 // Test a no-op change to the write FD partway through.
1665 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001666 ASSERT_TRUE(ssl);
1667 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1668 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1669 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001670
1671 // ASan builds will implicitly test that the internal |BIO| reference-counting
1672 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001673}
1674
David Benjaminf0d8e222017-02-04 10:58:26 -05001675TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001676 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001677 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001678
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001679 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1680 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001681 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001682 ASSERT_TRUE(ssl);
1683 ASSERT_TRUE(bio1);
1684 ASSERT_TRUE(bio2);
1685 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001686
1687 // SSL_set_bio takes one reference when the parameters are the same.
1688 BIO_up_ref(bio1.get());
1689 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1690
1691 // Repeating the call does nothing.
1692 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1693
1694 // It takes one reference each when the parameters are different.
1695 BIO_up_ref(bio2.get());
1696 BIO_up_ref(bio3.get());
1697 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1698
1699 // Repeating the call does nothing.
1700 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1701
1702 // It takes one reference when changing only wbio.
1703 BIO_up_ref(bio1.get());
1704 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1705
1706 // It takes one reference when changing only rbio and the two are different.
1707 BIO_up_ref(bio3.get());
1708 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1709
1710 // If setting wbio to rbio, it takes no additional references.
1711 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1712
1713 // From there, wbio may be switched to something else.
1714 BIO_up_ref(bio1.get());
1715 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1716
1717 // If setting rbio to wbio, it takes no additional references.
1718 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1719
1720 // From there, rbio may be switched to something else, but, for historical
1721 // reasons, it takes a reference to both parameters.
1722 BIO_up_ref(bio1.get());
1723 BIO_up_ref(bio2.get());
1724 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1725
1726 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1727 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001728}
1729
David Benjamin25490f22016-07-14 00:22:54 -04001730static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1731
David Benjamin0fef3052016-11-18 15:11:10 +09001732static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1733 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001734 bssl::UniquePtr<X509> cert = GetTestCertificate();
1735 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001736 if (!cert || !key) {
1737 return false;
1738 }
1739
David Benjamin0fef3052016-11-18 15:11:10 +09001740 // Configure both client and server to accept any certificate.
1741 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1742 if (!ctx ||
1743 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1744 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1745 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1746 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1747 return false;
1748 }
1749 SSL_CTX_set_verify(
1750 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1751 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001752
David Benjamin0fef3052016-11-18 15:11:10 +09001753 bssl::UniquePtr<SSL> client, server;
1754 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1755 nullptr /* no session */)) {
1756 return false;
1757 }
David Benjaminadd5e522016-07-14 00:33:24 -04001758
David Benjamin0fef3052016-11-18 15:11:10 +09001759 // Client and server should both see the leaf certificate.
1760 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1761 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1762 fprintf(stderr, "Server peer certificate did not match.\n");
1763 return false;
1764 }
David Benjaminadd5e522016-07-14 00:33:24 -04001765
David Benjamin0fef3052016-11-18 15:11:10 +09001766 peer.reset(SSL_get_peer_certificate(client.get()));
1767 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1768 fprintf(stderr, "Client peer certificate did not match.\n");
1769 return false;
1770 }
David Benjaminadd5e522016-07-14 00:33:24 -04001771
David Benjamin0fef3052016-11-18 15:11:10 +09001772 // However, for historical reasons, the chain includes the leaf on the
1773 // client, but does not on the server.
1774 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1775 fprintf(stderr, "Client peer chain was incorrect.\n");
1776 return false;
1777 }
David Benjaminadd5e522016-07-14 00:33:24 -04001778
David Benjamin0fef3052016-11-18 15:11:10 +09001779 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1780 fprintf(stderr, "Server peer chain was incorrect.\n");
1781 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001782 }
1783
1784 return true;
1785}
1786
David Benjamin0fef3052016-11-18 15:11:10 +09001787static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1788 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001789 bssl::UniquePtr<X509> cert = GetTestCertificate();
1790 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001791 if (!cert || !key) {
1792 return false;
1793 }
1794
1795 uint8_t *cert_der = NULL;
1796 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1797 if (cert_der_len < 0) {
1798 return false;
1799 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001800 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001801
1802 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1803 SHA256(cert_der, cert_der_len, cert_sha256);
1804
David Benjamin0fef3052016-11-18 15:11:10 +09001805 // Configure both client and server to accept any certificate, but the
1806 // server must retain only the SHA-256 of the peer.
1807 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1808 if (!ctx ||
1809 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1810 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1811 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1812 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1813 return false;
1814 }
1815 SSL_CTX_set_verify(
1816 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1817 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1818 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001819
David Benjamin0fef3052016-11-18 15:11:10 +09001820 bssl::UniquePtr<SSL> client, server;
1821 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1822 nullptr /* no session */)) {
1823 return false;
1824 }
David Benjamin25490f22016-07-14 00:22:54 -04001825
David Benjamin0fef3052016-11-18 15:11:10 +09001826 // The peer certificate has been dropped.
1827 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1828 if (peer) {
1829 fprintf(stderr, "Peer certificate was retained.\n");
1830 return false;
1831 }
David Benjamin25490f22016-07-14 00:22:54 -04001832
David Benjamin0fef3052016-11-18 15:11:10 +09001833 SSL_SESSION *session = SSL_get_session(server.get());
1834 if (!session->peer_sha256_valid) {
1835 fprintf(stderr, "peer_sha256_valid was not set.\n");
1836 return false;
1837 }
David Benjamin25490f22016-07-14 00:22:54 -04001838
David Benjamin17cf2cb2016-12-13 01:07:13 -05001839 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1840 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001841 fprintf(stderr, "peer_sha256 did not match.\n");
1842 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001843 }
1844
1845 return true;
1846}
1847
David Benjaminafc64de2016-07-19 17:12:41 +02001848static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1849 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001850 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001851 // Our default cipher list varies by CPU capabilities, so manually place the
1852 // ChaCha20 ciphers in front.
1853 const char* cipher_list =
1854#ifdef BORINGSSL_ENABLE_DHE_TLS
1855 "!DHE:CHACHA20:ALL";
1856#else
1857 "CHACHA20:ALL";
1858#endif
David Benjamin2dc02042016-09-19 19:57:37 -04001859 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001860 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001861 !SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
David Benjaminafc64de2016-07-19 17:12:41 +02001862 return false;
1863 }
David Benjamin2dc02042016-09-19 19:57:37 -04001864
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001865 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001866 if (!ssl) {
1867 return false;
1868 }
1869 std::vector<uint8_t> client_hello;
1870 if (!GetClientHello(ssl.get(), &client_hello)) {
1871 return false;
1872 }
1873
1874 // Zero the client_random.
1875 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1876 1 + 3 + // handshake message header
1877 2; // client_version
1878 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1879 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1880 return false;
1881 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001882 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001883
1884 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001885 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001886 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1887 fprintf(stderr, "Got:\n\t");
1888 for (size_t i = 0; i < client_hello.size(); i++) {
1889 fprintf(stderr, "0x%02x, ", client_hello[i]);
1890 }
1891 fprintf(stderr, "\nWanted:\n\t");
1892 for (size_t i = 0; i < expected_len; i++) {
1893 fprintf(stderr, "0x%02x, ", expected[i]);
1894 }
1895 fprintf(stderr, "\n");
1896 return false;
1897 }
1898
1899 return true;
1900}
1901
1902// Tests that our ClientHellos do not change unexpectedly.
1903static bool TestClientHello() {
1904 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001905 0x16,
1906 0x03, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001907 0x00, 0x3b,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001908 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001909 0x00, 0x00, 0x37,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001910 0x03, 0x00,
1911 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1912 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1915 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001916 0x00, 0x10,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001917 0xc0, 0x09,
1918 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001919 0xc0, 0x0a,
1920 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001921 0x00, 0x2f,
1922 0x00, 0x35,
1923 0x00, 0x0a,
1924 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001925 };
1926 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1927 sizeof(kSSL3ClientHello))) {
1928 return false;
1929 }
1930
1931 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001932 0x16,
1933 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001934 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001935 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001936 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001937 0x03, 0x01,
1938 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1939 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1942 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001943 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001944 0xc0, 0x09,
1945 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001946 0xc0, 0x0a,
1947 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001948 0x00, 0x2f,
1949 0x00, 0x35,
1950 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001951 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1952 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1953 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1954 };
1955 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1956 sizeof(kTLS1ClientHello))) {
1957 return false;
1958 }
1959
1960 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001961 0x16,
1962 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001963 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001964 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001965 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001966 0x03, 0x02,
1967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001972 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001973 0xc0, 0x09,
1974 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001975 0xc0, 0x0a,
1976 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001977 0x00, 0x2f,
1978 0x00, 0x35,
1979 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001980 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1981 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1982 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1983 };
1984 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1985 sizeof(kTLS11ClientHello))) {
1986 return false;
1987 }
1988
David Benjamin3b584332017-01-24 22:47:18 -05001989 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
1990 // builds.
1991#if defined(BORINGSSL_ANDROID_SYSTEM)
1992 return true;
1993#endif
1994
David Benjaminafc64de2016-07-19 17:12:41 +02001995 static const uint8_t kTLS12ClientHello[] = {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001996 0x16,
1997 0x03, 0x01,
1998 0x00, 0x8e,
1999 0x01,
2000 0x00, 0x00, 0x8a,
2001 0x03, 0x03,
David Benjamin57e929f2016-08-30 00:30:38 -04002002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2005 0x00, 0x2a,
2006 0xcc, 0xa9,
2007 0xcc, 0xa8,
2008 0xc0, 0x2b,
2009 0xc0, 0x2f,
2010 0xc0, 0x2c,
2011 0xc0, 0x30,
2012 0xc0, 0x09,
2013 0xc0, 0x23,
2014 0xc0, 0x13,
2015 0xc0, 0x27,
2016 0xc0, 0x0a,
2017 0xc0, 0x24,
2018 0xc0, 0x14,
2019 0xc0, 0x28,
2020 0x00, 0x9c,
2021 0x00, 0x9d,
2022 0x00, 0x2f,
2023 0x00, 0x3c,
2024 0x00, 0x35,
2025 0x00, 0x3d,
2026 0x00, 0x0a,
2027 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2028 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
2029 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
2030 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2031 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02002032 };
2033 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
2034 sizeof(kTLS12ClientHello))) {
2035 return false;
2036 }
2037
2038 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2039 // implementation has settled enough that it won't change.
2040
2041 return true;
2042}
2043
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002044static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002045
2046static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2047 // Save the most recent session.
2048 g_last_session.reset(session);
2049 return 1;
2050}
2051
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002052static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04002053 SSL_CTX *server_ctx) {
2054 g_last_session = nullptr;
2055 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2056
2057 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002058 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002059 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2060 nullptr /* no session */)) {
2061 fprintf(stderr, "Failed to connect client and server.\n");
2062 return nullptr;
2063 }
2064
2065 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2066 SSL_read(client.get(), nullptr, 0);
2067
2068 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2069
2070 if (!g_last_session) {
2071 fprintf(stderr, "Client did not receive a session.\n");
2072 return nullptr;
2073 }
2074 return std::move(g_last_session);
2075}
2076
2077static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2078 SSL_SESSION *session,
2079 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002080 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002081 if (!ConnectClientAndServer(&client, &server, client_ctx,
2082 server_ctx, session)) {
2083 fprintf(stderr, "Failed to connect client and server.\n");
2084 return false;
2085 }
2086
2087 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2088 fprintf(stderr, "Client and server were inconsistent.\n");
2089 return false;
2090 }
2091
2092 bool was_reused = !!SSL_session_reused(client.get());
2093 if (was_reused != reused) {
2094 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
2095 was_reused ? "" : " not");
2096 return false;
2097 }
2098
2099 return true;
2100}
2101
David Benjamin3c51d9b2016-11-01 17:50:42 -04002102static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2103 SSL_CTX *server_ctx,
2104 SSL_SESSION *session) {
2105 g_last_session = nullptr;
2106 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2107
2108 bssl::UniquePtr<SSL> client, server;
2109 if (!ConnectClientAndServer(&client, &server, client_ctx,
2110 server_ctx, session)) {
2111 fprintf(stderr, "Failed to connect client and server.\n");
2112 return nullptr;
2113 }
2114
2115 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2116 fprintf(stderr, "Client and server were inconsistent.\n");
2117 return nullptr;
2118 }
2119
2120 if (!SSL_session_reused(client.get())) {
2121 fprintf(stderr, "Session was not reused.\n");
2122 return nullptr;
2123 }
2124
2125 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2126 SSL_read(client.get(), nullptr, 0);
2127
2128 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2129
2130 if (!g_last_session) {
2131 fprintf(stderr, "Client did not receive a renewed session.\n");
2132 return nullptr;
2133 }
2134 return std::move(g_last_session);
2135}
2136
David Benjamina933c382016-10-28 00:10:03 -04002137static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2138 static const uint8_t kContext[] = {3};
2139
2140 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2141 return SSL_TLSEXT_ERR_ALERT_FATAL;
2142 }
2143
2144 return SSL_TLSEXT_ERR_OK;
2145}
2146
David Benjamin0fef3052016-11-18 15:11:10 +09002147static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2148 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002149 bssl::UniquePtr<X509> cert = GetTestCertificate();
2150 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002151 if (!cert || !key) {
2152 return false;
2153 }
2154
2155 static const uint8_t kContext1[] = {1};
2156 static const uint8_t kContext2[] = {2};
2157
David Benjamin0fef3052016-11-18 15:11:10 +09002158 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2159 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2160 if (!server_ctx || !client_ctx ||
2161 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2162 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2163 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2164 sizeof(kContext1)) ||
2165 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2166 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2167 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2168 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2169 return false;
2170 }
David Benjamina20e5352016-08-02 19:09:41 -04002171
David Benjamin0fef3052016-11-18 15:11:10 +09002172 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2173 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002174
David Benjamin0fef3052016-11-18 15:11:10 +09002175 bssl::UniquePtr<SSL_SESSION> session =
2176 CreateClientSession(client_ctx.get(), server_ctx.get());
2177 if (!session) {
2178 fprintf(stderr, "Error getting session.\n");
2179 return false;
2180 }
David Benjamina20e5352016-08-02 19:09:41 -04002181
David Benjamin0fef3052016-11-18 15:11:10 +09002182 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2183 true /* expect session reused */)) {
2184 fprintf(stderr, "Error resuming session.\n");
2185 return false;
2186 }
David Benjamina20e5352016-08-02 19:09:41 -04002187
David Benjamin0fef3052016-11-18 15:11:10 +09002188 // Change the session ID context.
2189 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2190 sizeof(kContext2))) {
2191 return false;
2192 }
David Benjamina20e5352016-08-02 19:09:41 -04002193
David Benjamin0fef3052016-11-18 15:11:10 +09002194 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2195 false /* expect session not reused */)) {
2196 fprintf(stderr, "Error connecting with a different context.\n");
2197 return false;
2198 }
David Benjamina933c382016-10-28 00:10:03 -04002199
David Benjamin0fef3052016-11-18 15:11:10 +09002200 // Change the session ID context back and install an SNI callback to switch
2201 // it.
2202 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2203 sizeof(kContext1))) {
2204 return false;
2205 }
David Benjamina933c382016-10-28 00:10:03 -04002206
David Benjamin0fef3052016-11-18 15:11:10 +09002207 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2208 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002209
David Benjamin0fef3052016-11-18 15:11:10 +09002210 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2211 false /* expect session not reused */)) {
2212 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2213 return false;
2214 }
David Benjamina933c382016-10-28 00:10:03 -04002215
David Benjamin0fef3052016-11-18 15:11:10 +09002216 // Switch the session ID context with the early callback instead.
2217 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002218 SSL_CTX_set_select_certificate_cb(
2219 server_ctx.get(),
2220 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2221 static const uint8_t kContext[] = {3};
2222
2223 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2224 sizeof(kContext))) {
2225 return ssl_select_cert_error;
2226 }
2227
2228 return ssl_select_cert_success;
2229 });
David Benjamina933c382016-10-28 00:10:03 -04002230
David Benjamin0fef3052016-11-18 15:11:10 +09002231 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2232 false /* expect session not reused */)) {
2233 fprintf(stderr,
2234 "Error connecting with a context switch on early callback.\n");
2235 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002236 }
2237
2238 return true;
2239}
2240
David Benjamin721e8b72016-08-03 13:13:17 -04002241static timeval g_current_time;
2242
2243static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2244 *out_clock = g_current_time;
2245}
2246
David Benjamin17b30832017-01-28 14:00:32 -05002247static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2248 out_clock->tv_sec = 1000;
2249 out_clock->tv_usec = 0;
2250}
2251
David Benjamin3c51d9b2016-11-01 17:50:42 -04002252static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2253 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2254 int encrypt) {
2255 static const uint8_t kZeros[16] = {0};
2256
2257 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002258 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002259 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002260 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002261 return 0;
2262 }
2263
2264 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2265 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2266 return -1;
2267 }
2268
2269 // Returning two from the callback in decrypt mode renews the
2270 // session in TLS 1.2 and below.
2271 return encrypt ? 1 : 2;
2272}
2273
David Benjamin123db572016-11-03 16:59:25 -04002274static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002275 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2276 return false;
2277 }
2278
David Benjamin123db572016-11-03 16:59:25 -04002279 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2280 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2281 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2282
David Benjamin9b63f292016-11-15 00:44:05 -05002283#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2284 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002285 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002286#else
2287 static const uint8_t kZeros[16] = {0};
2288 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002289 bssl::ScopedEVP_CIPHER_CTX ctx;
2290 int len1, len2;
2291 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2292 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2293 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2294 return false;
2295 }
2296
2297 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002298#endif
David Benjamin123db572016-11-03 16:59:25 -04002299
Adam Langley46db7af2017-02-01 15:49:37 -08002300 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2301 if (!ssl_ctx) {
2302 return false;
2303 }
David Benjamin123db572016-11-03 16:59:25 -04002304 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002305 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002306 if (!server_session) {
2307 return false;
2308 }
2309
2310 *out = server_session->time;
2311 return true;
2312}
2313
David Benjamin0fef3052016-11-18 15:11:10 +09002314static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2315 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002316 bssl::UniquePtr<X509> cert = GetTestCertificate();
2317 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002318 if (!cert || !key) {
2319 return false;
2320 }
2321
David Benjamin0fef3052016-11-18 15:11:10 +09002322 for (bool server_test : std::vector<bool>{false, true}) {
David Benjamin17b30832017-01-28 14:00:32 -05002323 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002324 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002325
David Benjamin17b30832017-01-28 14:00:32 -05002326 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2327 // resumptions still perform ECDHE.
2328 const time_t timeout = version == TLS1_3_VERSION
2329 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2330 : SSL_DEFAULT_SESSION_TIMEOUT;
2331
David Benjamin0fef3052016-11-18 15:11:10 +09002332 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2333 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2334 if (!server_ctx || !client_ctx ||
2335 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2336 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2337 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2338 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2339 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2340 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2341 return false;
2342 }
2343
2344 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2345 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2346
David Benjamin17b30832017-01-28 14:00:32 -05002347 // Both client and server must enforce session timeouts. We configure the
2348 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002349 if (server_test) {
David Benjamin17b30832017-01-28 14:00:32 -05002350 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002351 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2352 } else {
2353 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
David Benjamin17b30832017-01-28 14:00:32 -05002354 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002355 }
2356
2357 // Configure a ticket callback which renews tickets.
2358 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2359
2360 bssl::UniquePtr<SSL_SESSION> session =
2361 CreateClientSession(client_ctx.get(), server_ctx.get());
2362 if (!session) {
2363 fprintf(stderr, "Error getting session.\n");
2364 return false;
2365 }
2366
2367 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002368 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002369
2370 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2371 true /* expect session reused */)) {
2372 fprintf(stderr, "Error resuming session.\n");
2373 return false;
2374 }
2375
2376 // Advance the clock one more second.
2377 g_current_time.tv_sec++;
2378
2379 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2380 false /* expect session not reused */)) {
2381 fprintf(stderr, "Error resuming session.\n");
2382 return false;
2383 }
2384
2385 // Rewind the clock to before the session was minted.
2386 g_current_time.tv_sec = kStartTime - 1;
2387
2388 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2389 false /* expect session not reused */)) {
2390 fprintf(stderr, "Error resuming session.\n");
2391 return false;
2392 }
2393
2394 // SSL 3.0 cannot renew sessions.
2395 if (version == SSL3_VERSION) {
2396 continue;
2397 }
2398
2399 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002400 time_t new_start_time = kStartTime + timeout - 10;
2401 g_current_time.tv_sec = new_start_time;
David Benjamin0fef3052016-11-18 15:11:10 +09002402 bssl::UniquePtr<SSL_SESSION> new_session =
2403 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2404 if (!new_session) {
2405 fprintf(stderr, "Error renewing session.\n");
2406 return false;
2407 }
2408
2409 // This new session is not the same object as before.
2410 if (session.get() == new_session.get()) {
2411 fprintf(stderr, "New and old sessions alias.\n");
2412 return false;
2413 }
2414
2415 // Check the sessions have timestamps measured from issuance.
2416 long session_time = 0;
2417 if (server_test) {
2418 if (!GetServerTicketTime(&session_time, new_session.get())) {
2419 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002420 return false;
2421 }
David Benjamin0fef3052016-11-18 15:11:10 +09002422 } else {
2423 session_time = new_session->time;
2424 }
David Benjamin721e8b72016-08-03 13:13:17 -04002425
David Benjamin0fef3052016-11-18 15:11:10 +09002426 if (session_time != g_current_time.tv_sec) {
2427 fprintf(stderr, "New session is not measured from issuance.\n");
2428 return false;
2429 }
David Benjamin721e8b72016-08-03 13:13:17 -04002430
David Benjamin17b30832017-01-28 14:00:32 -05002431 if (version == TLS1_3_VERSION) {
2432 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2433 // lifetime TLS 1.3.
2434 g_current_time.tv_sec = new_start_time + timeout - 1;
2435 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2436 new_session.get(),
2437 true /* expect session reused */)) {
2438 fprintf(stderr, "Error resuming renewed session.\n");
2439 return false;
2440 }
David Benjamin721e8b72016-08-03 13:13:17 -04002441
David Benjamin17b30832017-01-28 14:00:32 -05002442 // The new session expires after the new timeout.
2443 g_current_time.tv_sec = new_start_time + timeout + 1;
2444 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2445 new_session.get(),
2446 false /* expect session ot reused */)) {
2447 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2448 return false;
2449 }
2450
2451 // Renew the session until it begins just past the auth timeout.
2452 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2453 while (new_start_time < auth_end_time - 1000) {
2454 // Get as close as possible to target start time.
2455 new_start_time =
2456 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2457 g_current_time.tv_sec = new_start_time;
2458 new_session = ExpectSessionRenewed(client_ctx.get(), server_ctx.get(),
2459 new_session.get());
2460 if (!new_session) {
2461 fprintf(stderr, "Error renewing session.\n");
2462 return false;
2463 }
2464 }
2465
2466 // Now the session's lifetime is bound by the auth timeout.
2467 g_current_time.tv_sec = auth_end_time - 1;
2468 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2469 new_session.get(),
2470 true /* expect session reused */)) {
2471 fprintf(stderr, "Error resuming renewed session.\n");
2472 return false;
2473 }
2474
2475 g_current_time.tv_sec = auth_end_time + 1;
2476 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2477 new_session.get(),
2478 false /* expect session ot reused */)) {
2479 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2480 return false;
2481 }
2482 } else {
2483 // The new session is usable just before the old expiration.
2484 g_current_time.tv_sec = kStartTime + timeout - 1;
2485 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2486 new_session.get(),
2487 true /* expect session reused */)) {
2488 fprintf(stderr, "Error resuming renewed session.\n");
2489 return false;
2490 }
2491
2492 // Renewal does not extend the lifetime, so it is not usable beyond the
2493 // old expiration.
2494 g_current_time.tv_sec = kStartTime + timeout + 1;
2495 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2496 new_session.get(),
2497 false /* expect session not reused */)) {
2498 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2499 return false;
2500 }
David Benjamin1b22f852016-10-27 16:36:32 -04002501 }
David Benjamin721e8b72016-08-03 13:13:17 -04002502 }
2503
2504 return true;
2505}
2506
David Benjamin0fc37ef2016-08-17 15:29:46 -04002507static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2508 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2509 SSL_set_SSL_CTX(ssl, ctx);
2510 return SSL_TLSEXT_ERR_OK;
2511}
2512
David Benjamin0fef3052016-11-18 15:11:10 +09002513static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2514 uint16_t version) {
2515 // SSL 3.0 lacks extensions.
2516 if (version == SSL3_VERSION) {
2517 return true;
2518 }
2519
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002520 bssl::UniquePtr<X509> cert = GetTestCertificate();
2521 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2522 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2523 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002524 if (!cert || !key || !cert2 || !key2) {
2525 return false;
2526 }
2527
David Benjamin0fef3052016-11-18 15:11:10 +09002528 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2529 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002530
David Benjamin83a32122017-02-14 18:34:54 -05002531 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2532 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2533
David Benjamin0fef3052016-11-18 15:11:10 +09002534 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2535 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2536 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2537 if (!server_ctx || !server_ctx2 || !client_ctx ||
2538 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2539 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2540 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2541 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
David Benjamin83a32122017-02-14 18:34:54 -05002542 !SSL_CTX_set_signed_cert_timestamp_list(server_ctx2.get(), kSCTList,
2543 sizeof(kSCTList)) ||
2544 !SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2545 sizeof(kOCSPResponse)) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002546 // Historically signing preferences would be lost in some cases with the
2547 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2548 // this doesn't happen when |version| is TLS 1.2, configure the private
2549 // key to only sign SHA-256.
2550 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2551 1) ||
2552 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2553 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2554 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2555 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2556 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2557 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2558 return false;
2559 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002560
David Benjamin0fef3052016-11-18 15:11:10 +09002561 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2562 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002563
David Benjamin83a32122017-02-14 18:34:54 -05002564 SSL_CTX_enable_signed_cert_timestamps(client_ctx.get());
2565 SSL_CTX_enable_ocsp_stapling(client_ctx.get());
2566
David Benjamin0fef3052016-11-18 15:11:10 +09002567 bssl::UniquePtr<SSL> client, server;
2568 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2569 server_ctx.get(), nullptr)) {
2570 fprintf(stderr, "Handshake failed.\n");
2571 return false;
2572 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002573
David Benjamin0fef3052016-11-18 15:11:10 +09002574 // The client should have received |cert2|.
2575 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2576 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2577 fprintf(stderr, "Incorrect certificate received.\n");
2578 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002579 }
2580
David Benjamin83a32122017-02-14 18:34:54 -05002581 // The client should have received |server_ctx2|'s SCT list.
2582 const uint8_t *data;
2583 size_t len;
2584 SSL_get0_signed_cert_timestamp_list(client.get(), &data, &len);
2585 if (Bytes(kSCTList) != Bytes(data, len)) {
2586 fprintf(stderr, "Incorrect SCT list received.\n");
2587 return false;
2588 }
2589
2590 // The client should have received |server_ctx2|'s OCSP response.
2591 SSL_get0_ocsp_response(client.get(), &data, &len);
2592 if (Bytes(kOCSPResponse) != Bytes(data, len)) {
2593 fprintf(stderr, "Incorrect OCSP response received.\n");
2594 return false;
2595 }
2596
David Benjamin0fc37ef2016-08-17 15:29:46 -04002597 return true;
2598}
2599
David Benjaminf0d8e222017-02-04 10:58:26 -05002600// Test that the early callback can swap the maximum version.
2601TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002602 bssl::UniquePtr<X509> cert = GetTestCertificate();
2603 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2604 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2605 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002606 ASSERT_TRUE(cert);
2607 ASSERT_TRUE(key);
2608 ASSERT_TRUE(server_ctx);
2609 ASSERT_TRUE(client_ctx);
2610 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2611 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2612 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2613 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002614
David Benjaminf0d8e222017-02-04 10:58:26 -05002615 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002616 server_ctx.get(),
2617 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002618 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002619 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002620 }
2621
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002622 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002623 });
David Benjamin99620572016-08-30 00:35:36 -04002624
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002625 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002626 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2627 server_ctx.get(), nullptr));
2628 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002629}
2630
David Benjaminf0d8e222017-02-04 10:58:26 -05002631TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002632 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002633 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002634
David Benjaminf0d8e222017-02-04 10:58:26 -05002635 // Set valid TLS versions.
2636 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2637 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2638 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2639 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002640
David Benjaminf0d8e222017-02-04 10:58:26 -05002641 // Invalid TLS versions are rejected.
2642 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2643 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2644 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2645 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2646 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2647 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002648
David Benjaminf0d8e222017-02-04 10:58:26 -05002649 // Zero is the default version.
2650 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2651 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2652 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2653 EXPECT_EQ(SSL3_VERSION, ctx->min_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002654
David Benjamin2dc02042016-09-19 19:57:37 -04002655 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002656 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002657
David Benjaminf0d8e222017-02-04 10:58:26 -05002658 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2659 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2660 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2661 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002662
David Benjaminf0d8e222017-02-04 10:58:26 -05002663 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2664 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2665 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2666 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2667 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2668 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2669 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2670 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002671
David Benjaminf0d8e222017-02-04 10:58:26 -05002672 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2673 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2674 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2675 EXPECT_EQ(TLS1_1_VERSION, ctx->min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002676}
2677
David Benjamin458334a2016-12-15 13:53:25 -05002678static const char *GetVersionName(uint16_t version) {
2679 switch (version) {
2680 case SSL3_VERSION:
2681 return "SSLv3";
2682 case TLS1_VERSION:
2683 return "TLSv1";
2684 case TLS1_1_VERSION:
2685 return "TLSv1.1";
2686 case TLS1_2_VERSION:
2687 return "TLSv1.2";
2688 case TLS1_3_VERSION:
2689 return "TLSv1.3";
2690 case DTLS1_VERSION:
2691 return "DTLSv1";
2692 case DTLS1_2_VERSION:
2693 return "DTLSv1.2";
2694 default:
2695 return "???";
2696 }
2697}
2698
David Benjamin0fef3052016-11-18 15:11:10 +09002699static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2700 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002701 bssl::UniquePtr<X509> cert = GetTestCertificate();
2702 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2703 if (!cert || !key) {
2704 return false;
2705 }
2706
David Benjamin0fef3052016-11-18 15:11:10 +09002707 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2708 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2709 bssl::UniquePtr<SSL> client, server;
2710 if (!server_ctx || !client_ctx ||
2711 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2712 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2713 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2714 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2715 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2716 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2717 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2718 server_ctx.get(), nullptr /* no session */)) {
2719 fprintf(stderr, "Failed to connect.\n");
2720 return false;
2721 }
David Benjamincb18ac22016-09-27 14:09:15 -04002722
David Benjamin0fef3052016-11-18 15:11:10 +09002723 if (SSL_version(client.get()) != version ||
2724 SSL_version(server.get()) != version) {
2725 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2726 SSL_version(client.get()), SSL_version(server.get()), version);
2727 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002728 }
2729
David Benjamin458334a2016-12-15 13:53:25 -05002730 // Test the version name is reported as expected.
2731 const char *version_name = GetVersionName(version);
2732 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2733 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2734 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2735 SSL_get_version(client.get()), SSL_get_version(server.get()),
2736 version_name);
2737 return false;
2738 }
2739
2740 // Test SSL_SESSION reports the same name.
2741 const char *client_name =
2742 SSL_SESSION_get_version(SSL_get_session(client.get()));
2743 const char *server_name =
2744 SSL_SESSION_get_version(SSL_get_session(server.get()));
2745 if (strcmp(version_name, client_name) != 0 ||
2746 strcmp(version_name, server_name) != 0) {
2747 fprintf(stderr,
2748 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2749 client_name, server_name, version_name);
2750 return false;
2751 }
2752
David Benjamincb18ac22016-09-27 14:09:15 -04002753 return true;
2754}
2755
David Benjamin9ef31f02016-10-31 18:01:13 -04002756// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2757// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002758static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2759 uint16_t version) {
2760 // SSL 3.0 lacks extensions.
2761 if (version == SSL3_VERSION) {
2762 return true;
2763 }
2764
David Benjamin9ef31f02016-10-31 18:01:13 -04002765 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2766
2767 bssl::UniquePtr<X509> cert = GetTestCertificate();
2768 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2769 if (!cert || !key) {
2770 return false;
2771 }
2772
David Benjamin0fef3052016-11-18 15:11:10 +09002773 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2774 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2775 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2776 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2777 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2778 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2779 0) {
2780 return false;
2781 }
2782
2783 // The ALPN callback does not fail the handshake on error, so have the
2784 // callback write a boolean.
2785 std::pair<uint16_t, bool> callback_state(version, false);
2786 SSL_CTX_set_alpn_select_cb(
2787 ctx.get(),
2788 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2789 unsigned in_len, void *arg) -> int {
2790 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2791 if (SSL_get_pending_cipher(ssl) != nullptr &&
2792 SSL_version(ssl) == state->first) {
2793 state->second = true;
2794 }
2795 return SSL_TLSEXT_ERR_NOACK;
2796 },
2797 &callback_state);
2798
2799 bssl::UniquePtr<SSL> client, server;
2800 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2801 nullptr /* no session */)) {
2802 return false;
2803 }
2804
2805 if (!callback_state.second) {
2806 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2807 return false;
2808 }
2809
2810 return true;
2811}
2812
David Benjaminb79cc842016-12-07 15:57:14 -05002813static bool TestSSLClearSessionResumption(bool is_dtls,
2814 const SSL_METHOD *method,
2815 uint16_t version) {
2816 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2817 // API pattern.
2818 if (version == TLS1_3_VERSION) {
2819 return true;
2820 }
2821
2822 bssl::UniquePtr<X509> cert = GetTestCertificate();
2823 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2824 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2825 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2826 if (!cert || !key || !server_ctx || !client_ctx ||
2827 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2828 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2829 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2830 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2831 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2832 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2833 return false;
2834 }
2835
2836 // Connect a client and a server.
2837 bssl::UniquePtr<SSL> client, server;
2838 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2839 server_ctx.get(), nullptr /* no session */)) {
2840 return false;
2841 }
2842
2843 if (SSL_session_reused(client.get()) ||
2844 SSL_session_reused(server.get())) {
2845 fprintf(stderr, "Session unexpectedly reused.\n");
2846 return false;
2847 }
2848
2849 // Reset everything.
2850 if (!SSL_clear(client.get()) ||
2851 !SSL_clear(server.get())) {
2852 fprintf(stderr, "SSL_clear failed.\n");
2853 return false;
2854 }
2855
2856 // Attempt to connect a second time.
2857 if (!CompleteHandshakes(client.get(), server.get())) {
2858 fprintf(stderr, "Could not reuse SSL objects.\n");
2859 return false;
2860 }
2861
2862 // |SSL_clear| should implicitly offer the previous session to the server.
2863 if (!SSL_session_reused(client.get()) ||
2864 !SSL_session_reused(server.get())) {
2865 fprintf(stderr, "Session was not reused in second try.\n");
2866 return false;
2867 }
2868
2869 return true;
2870}
2871
David Benjamin1444c3a2016-12-20 17:23:11 -05002872static bool ChainsEqual(STACK_OF(X509) *chain,
2873 const std::vector<X509 *> &expected) {
2874 if (sk_X509_num(chain) != expected.size()) {
2875 return false;
2876 }
2877
2878 for (size_t i = 0; i < expected.size(); i++) {
2879 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2880 return false;
2881 }
2882 }
2883
2884 return true;
2885}
2886
2887static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2888 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002889 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2890 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2891 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2892 if (!cert || !intermediate || !key) {
2893 return false;
2894 }
2895
2896 // Configure both client and server to accept any certificate. Add
2897 // |intermediate| to the cert store.
2898 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2899 if (!ctx ||
2900 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2901 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2902 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2903 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2904 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2905 intermediate.get())) {
2906 return false;
2907 }
2908 SSL_CTX_set_verify(
2909 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2910 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2911
2912 // By default, the client and server should each only send the leaf.
2913 bssl::UniquePtr<SSL> client, server;
2914 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2915 nullptr /* no session */)) {
2916 return false;
2917 }
2918
2919 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2920 fprintf(stderr, "Client-received chain did not match.\n");
2921 return false;
2922 }
2923
2924 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2925 fprintf(stderr, "Server-received chain did not match.\n");
2926 return false;
2927 }
2928
2929 // If auto-chaining is enabled, then the intermediate is sent.
2930 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2931 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2932 nullptr /* no session */)) {
2933 return false;
2934 }
2935
2936 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2937 {cert.get(), intermediate.get()})) {
2938 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2939 return false;
2940 }
2941
2942 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2943 {cert.get(), intermediate.get()})) {
2944 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2945 return false;
2946 }
2947
2948 // Auto-chaining does not override explicitly-configured intermediates.
2949 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2950 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2951 nullptr /* no session */)) {
2952 return false;
2953 }
2954
2955 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2956 {cert.get(), cert.get()})) {
2957 fprintf(stderr,
2958 "Client-received chain did not match (auto-chaining, explicit "
2959 "intermediate).\n");
2960 return false;
2961 }
2962
2963 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2964 {cert.get(), cert.get()})) {
2965 fprintf(stderr,
2966 "Server-received chain did not match (auto-chaining, explicit "
2967 "intermediate).\n");
2968 return false;
2969 }
2970
2971 return true;
2972}
2973
David Benjamin48063c22017-01-01 23:56:36 -05002974static bool ExpectBadWriteRetry() {
2975 int err = ERR_get_error();
2976 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2977 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2978 char buf[ERR_ERROR_STRING_BUF_LEN];
2979 ERR_error_string_n(err, buf, sizeof(buf));
2980 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2981 return false;
2982 }
2983
2984 if (ERR_peek_error() != 0) {
2985 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2986 return false;
2987 }
2988
2989 return true;
2990}
2991
2992static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
2993 uint16_t version) {
2994 if (is_dtls) {
2995 return true;
2996 }
2997
2998 for (bool enable_partial_write : std::vector<bool>{false, true}) {
2999 // Connect a client and server.
3000 bssl::UniquePtr<X509> cert = GetTestCertificate();
3001 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3002 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
3003 bssl::UniquePtr<SSL> client, server;
3004 if (!cert || !key || !ctx ||
3005 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
3006 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
3007 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
3008 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
3009 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
3010 nullptr /* no session */)) {
3011 return false;
3012 }
3013
3014 if (enable_partial_write) {
3015 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
3016 }
3017
3018 // Write without reading until the buffer is full and we have an unfinished
3019 // write. Keep a count so we may reread it again later. "hello!" will be
3020 // written in two chunks, "hello" and "!".
3021 char data[] = "hello!";
3022 static const int kChunkLen = 5; // The length of "hello".
3023 unsigned count = 0;
3024 for (;;) {
3025 int ret = SSL_write(client.get(), data, kChunkLen);
3026 if (ret <= 0) {
3027 int err = SSL_get_error(client.get(), ret);
3028 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
3029 break;
3030 }
3031 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
3032 return false;
3033 }
3034
3035 if (ret != 5) {
3036 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
3037 return false;
3038 }
3039
3040 count++;
3041 }
3042
3043 // Retrying with the same parameters is legal.
3044 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
3045 SSL_ERROR_WANT_WRITE) {
3046 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3047 return false;
3048 }
3049
3050 // Retrying with the same buffer but shorter length is not legal.
3051 if (SSL_get_error(client.get(),
3052 SSL_write(client.get(), data, kChunkLen - 1)) !=
3053 SSL_ERROR_SSL ||
3054 !ExpectBadWriteRetry()) {
3055 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3056 return false;
3057 }
3058
3059 // Retrying with a different buffer pointer is not legal.
3060 char data2[] = "hello";
3061 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
3062 kChunkLen)) != SSL_ERROR_SSL ||
3063 !ExpectBadWriteRetry()) {
3064 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3065 return false;
3066 }
3067
3068 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
3069 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3070 if (SSL_get_error(client.get(),
3071 SSL_write(client.get(), data2, kChunkLen)) !=
3072 SSL_ERROR_WANT_WRITE) {
3073 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3074 return false;
3075 }
3076
3077 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
3078 if (SSL_get_error(client.get(),
3079 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3080 SSL_ERROR_SSL ||
3081 !ExpectBadWriteRetry()) {
3082 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3083 return false;
3084 }
3085
3086 // Retrying with a larger buffer is legal.
3087 if (SSL_get_error(client.get(),
3088 SSL_write(client.get(), data, kChunkLen + 1)) !=
3089 SSL_ERROR_WANT_WRITE) {
3090 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3091 return false;
3092 }
3093
3094 // Drain the buffer.
3095 char buf[20];
3096 for (unsigned i = 0; i < count; i++) {
3097 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3098 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3099 fprintf(stderr, "Failed to read initial records.\n");
3100 return false;
3101 }
3102 }
3103
3104 // Now that there is space, a retry with a larger buffer should flush the
3105 // pending record, skip over that many bytes of input (on assumption they
3106 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3107 // is set, this will complete in two steps.
3108 char data3[] = "_____!";
3109 if (enable_partial_write) {
3110 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3111 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3112 fprintf(stderr, "SSL_write retry failed.\n");
3113 return false;
3114 }
3115 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3116 fprintf(stderr, "SSL_write retry failed.\n");
3117 return false;
3118 }
3119
3120 // Check the last write was correct. The data will be spread over two
3121 // records, so SSL_read returns twice.
3122 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3123 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3124 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3125 buf[0] != '!') {
3126 fprintf(stderr, "Failed to read write retry.\n");
3127 return false;
3128 }
3129 }
3130
3131 return true;
3132}
3133
David Benjamin0fef3052016-11-18 15:11:10 +09003134static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3135 const SSL_METHOD *method,
3136 uint16_t version)) {
3137 static uint16_t kTLSVersions[] = {
David Benjamin3b584332017-01-24 22:47:18 -05003138 SSL3_VERSION,
3139 TLS1_VERSION,
3140 TLS1_1_VERSION,
3141 TLS1_2_VERSION,
3142// TLS 1.3 requires RSA-PSS, which is disabled for Android system builds.
3143#if !defined(BORINGSSL_ANDROID_SYSTEM)
3144 TLS1_3_VERSION,
3145#endif
David Benjamin0fef3052016-11-18 15:11:10 +09003146 };
3147
3148 static uint16_t kDTLSVersions[] = {
3149 DTLS1_VERSION, DTLS1_2_VERSION,
3150 };
3151
David Benjamin9ef31f02016-10-31 18:01:13 -04003152 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003153 if (!test_func(false, TLS_method(), version)) {
3154 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003155 return false;
3156 }
David Benjamin0fef3052016-11-18 15:11:10 +09003157 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003158
David Benjamin0fef3052016-11-18 15:11:10 +09003159 for (uint16_t version : kDTLSVersions) {
3160 if (!test_func(true, DTLS_method(), version)) {
3161 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003162 return false;
3163 }
3164 }
3165
3166 return true;
3167}
3168
Adam Langleye1e78132017-01-31 15:24:31 -08003169TEST(SSLTest, AddChainCertHack) {
3170 // Ensure that we don't accidently break the hack that we have in place to
3171 // keep curl and serf happy when they use an |X509| even after transfering
3172 // ownership.
3173
3174 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3175 ASSERT_TRUE(ctx);
3176 X509 *cert = GetTestCertificate().release();
3177 ASSERT_TRUE(cert);
3178 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3179
3180 // This should not trigger a use-after-free.
3181 X509_cmp(cert, cert);
3182}
3183
David Benjaminb2ff2622017-02-03 17:06:18 -05003184TEST(SSLTest, GetCertificate) {
3185 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3186 ASSERT_TRUE(ctx);
3187 bssl::UniquePtr<X509> cert = GetTestCertificate();
3188 ASSERT_TRUE(cert);
3189 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3190 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3191 ASSERT_TRUE(ssl);
3192
3193 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3194 ASSERT_TRUE(cert2);
3195 X509 *cert3 = SSL_get_certificate(ssl.get());
3196 ASSERT_TRUE(cert3);
3197
3198 // The old and new certificates must be identical.
3199 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3200 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3201
3202 uint8_t *der = nullptr;
3203 long der_len = i2d_X509(cert.get(), &der);
3204 ASSERT_LT(0, der_len);
3205 bssl::UniquePtr<uint8_t> free_der(der);
3206
3207 uint8_t *der2 = nullptr;
3208 long der2_len = i2d_X509(cert2, &der2);
3209 ASSERT_LT(0, der2_len);
3210 bssl::UniquePtr<uint8_t> free_der2(der2);
3211
3212 uint8_t *der3 = nullptr;
3213 long der3_len = i2d_X509(cert3, &der3);
3214 ASSERT_LT(0, der3_len);
3215 bssl::UniquePtr<uint8_t> free_der3(der3);
3216
3217 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003218 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3219 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003220}
3221
Adam Langleyd04ca952017-02-28 11:26:51 -08003222TEST(SSLTest, SetChainAndKeyMismatch) {
3223 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3224 ASSERT_TRUE(ctx);
3225
3226 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3227 ASSERT_TRUE(key);
3228 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3229 ASSERT_TRUE(leaf);
3230 std::vector<CRYPTO_BUFFER*> chain = {
3231 leaf.get(),
3232 };
3233
3234 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3235 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3236 key.get(), nullptr));
3237 ERR_clear_error();
3238}
3239
3240TEST(SSLTest, SetChainAndKey) {
3241 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3242 ASSERT_TRUE(client_ctx);
3243 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3244 ASSERT_TRUE(server_ctx);
3245
3246 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3247 ASSERT_TRUE(key);
3248 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3249 ASSERT_TRUE(leaf);
3250 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3251 GetChainTestIntermediateBuffer();
3252 ASSERT_TRUE(intermediate);
3253 std::vector<CRYPTO_BUFFER*> chain = {
3254 leaf.get(), intermediate.get(),
3255 };
3256 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3257 chain.size(), key.get(), nullptr));
3258
3259 SSL_CTX_i_promise_to_verify_certs_after_the_handshake(client_ctx.get());
3260
3261 bssl::UniquePtr<SSL> client, server;
3262 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3263 server_ctx.get(),
3264 nullptr /* no session */));
3265}
3266
David Benjamin91222b82017-03-09 20:10:56 -05003267// Configuring the empty cipher list, though an error, should still modify the
3268// configuration.
3269TEST(SSLTest, EmptyCipherList) {
3270 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3271 ASSERT_TRUE(ctx);
3272
3273 // Initially, the cipher list is not empty.
3274 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3275
3276 // Configuring the empty cipher list fails.
3277 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3278 ERR_clear_error();
3279
3280 // But the cipher list is still updated to empty.
3281 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3282}
3283
Adam Langley4c341d02017-03-08 19:33:21 -08003284// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3285// test |SSL_TICKET_AEAD_METHOD| can fail.
3286enum ssl_test_ticket_aead_failure_mode {
3287 ssl_test_ticket_aead_ok = 0,
3288 ssl_test_ticket_aead_seal_fail,
3289 ssl_test_ticket_aead_open_soft_fail,
3290 ssl_test_ticket_aead_open_hard_fail,
3291};
3292
3293struct ssl_test_ticket_aead_state {
3294 unsigned retry_count;
3295 ssl_test_ticket_aead_failure_mode failure_mode;
3296};
3297
3298static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3299 const CRYPTO_EX_DATA *from,
3300 void **from_d, int index,
3301 long argl, void *argp) {
3302 abort();
3303}
3304
3305static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3306 CRYPTO_EX_DATA *ad, int index,
3307 long argl, void *argp) {
3308 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3309 if (state == nullptr) {
3310 return;
3311 }
3312
3313 OPENSSL_free(state);
3314}
3315
3316static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3317static int g_ssl_test_ticket_aead_ex_index;
3318
3319static int ssl_test_ticket_aead_get_ex_index() {
3320 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3321 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3322 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3323 ssl_test_ticket_aead_ex_index_free);
3324 });
3325 return g_ssl_test_ticket_aead_ex_index;
3326}
3327
3328static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3329 return 1;
3330}
3331
3332static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3333 size_t max_out_len, const uint8_t *in,
3334 size_t in_len) {
3335 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3336 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3337
3338 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3339 max_out_len < in_len + 1) {
3340 return 0;
3341 }
3342
3343 OPENSSL_memmove(out, in, in_len);
3344 out[in_len] = 0xff;
3345 *out_len = in_len + 1;
3346
3347 return 1;
3348}
3349
3350static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3351 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3352 const uint8_t *in, size_t in_len) {
3353 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3354 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3355
3356 if (state->retry_count > 0) {
3357 state->retry_count--;
3358 return ssl_ticket_aead_retry;
3359 }
3360
3361 switch (state->failure_mode) {
3362 case ssl_test_ticket_aead_ok:
3363 break;
3364 case ssl_test_ticket_aead_seal_fail:
3365 // If |seal| failed then there shouldn't be any ticket to try and
3366 // decrypt.
3367 abort();
3368 break;
3369 case ssl_test_ticket_aead_open_soft_fail:
3370 return ssl_ticket_aead_ignore_ticket;
3371 case ssl_test_ticket_aead_open_hard_fail:
3372 return ssl_ticket_aead_error;
3373 }
3374
3375 if (in_len == 0 || in[in_len - 1] != 0xff) {
3376 return ssl_ticket_aead_ignore_ticket;
3377 }
3378
3379 if (max_out_len < in_len - 1) {
3380 return ssl_ticket_aead_error;
3381 }
3382
3383 OPENSSL_memmove(out, in, in_len - 1);
3384 *out_len = in_len - 1;
3385 return ssl_ticket_aead_success;
3386}
3387
3388static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3389 ssl_test_ticket_aead_max_overhead,
3390 ssl_test_ticket_aead_seal,
3391 ssl_test_ticket_aead_open,
3392};
3393
3394static void ConnectClientAndServerWithTicketMethod(
3395 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3396 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3397 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3398 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3399 ASSERT_TRUE(client);
3400 ASSERT_TRUE(server);
3401 SSL_set_connect_state(client.get());
3402 SSL_set_accept_state(server.get());
3403
3404 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3405 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3406 ASSERT_TRUE(state);
3407 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3408 state->retry_count = retry_count;
3409 state->failure_mode = failure_mode;
3410
3411 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3412 state));
3413
3414 SSL_set_session(client.get(), session);
3415
3416 BIO *bio1, *bio2;
3417 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3418
3419 // SSL_set_bio takes ownership.
3420 SSL_set_bio(client.get(), bio1, bio1);
3421 SSL_set_bio(server.get(), bio2, bio2);
3422
3423 if (CompleteHandshakes(client.get(), server.get())) {
3424 *out_client = std::move(client);
3425 *out_server = std::move(server);
3426 } else {
3427 out_client->reset();
3428 out_server->reset();
3429 }
3430}
3431
3432class TicketAEADMethodTest
3433 : public ::testing::TestWithParam<testing::tuple<
3434 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3435
3436TEST_P(TicketAEADMethodTest, Resume) {
3437 bssl::UniquePtr<X509> cert = GetTestCertificate();
3438 ASSERT_TRUE(cert);
3439 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3440 ASSERT_TRUE(key);
3441
3442 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3443 ASSERT_TRUE(server_ctx);
3444 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3445 ASSERT_TRUE(client_ctx);
3446
3447 const uint16_t version = testing::get<0>(GetParam());
3448 const unsigned retry_count = testing::get<1>(GetParam());
3449 const ssl_test_ticket_aead_failure_mode failure_mode =
3450 testing::get<2>(GetParam());
3451
3452 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3453 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3454 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3455 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3456 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3457 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3458
3459 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3460 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3461 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3462 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003463 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003464
3465 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3466
3467 bssl::UniquePtr<SSL> client, server;
3468 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3469 server_ctx.get(), retry_count,
3470 failure_mode, nullptr);
3471 switch (failure_mode) {
3472 case ssl_test_ticket_aead_ok:
3473 case ssl_test_ticket_aead_open_hard_fail:
3474 case ssl_test_ticket_aead_open_soft_fail:
3475 ASSERT_TRUE(client);
3476 break;
3477 case ssl_test_ticket_aead_seal_fail:
3478 EXPECT_FALSE(client);
3479 return;
3480 }
3481 EXPECT_FALSE(SSL_session_reused(client.get()));
3482 EXPECT_FALSE(SSL_session_reused(server.get()));
3483
David Benjamin707af292017-03-10 17:47:18 -05003484 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3485 SSL_read(client.get(), nullptr, 0);
3486
3487 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003488 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3489 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003490 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003491 switch (failure_mode) {
3492 case ssl_test_ticket_aead_ok:
3493 ASSERT_TRUE(client);
3494 EXPECT_TRUE(SSL_session_reused(client.get()));
3495 EXPECT_TRUE(SSL_session_reused(server.get()));
3496 break;
3497 case ssl_test_ticket_aead_seal_fail:
3498 abort();
3499 break;
3500 case ssl_test_ticket_aead_open_hard_fail:
3501 EXPECT_FALSE(client);
3502 break;
3503 case ssl_test_ticket_aead_open_soft_fail:
3504 ASSERT_TRUE(client);
3505 EXPECT_FALSE(SSL_session_reused(client.get()));
3506 EXPECT_FALSE(SSL_session_reused(server.get()));
3507 }
3508}
3509
3510INSTANTIATE_TEST_CASE_P(
3511 TicketAEADMethodTests, TicketAEADMethodTest,
3512 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003513 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003514 testing::Values(0, 1, 2),
3515 testing::Values(ssl_test_ticket_aead_ok,
3516 ssl_test_ticket_aead_seal_fail,
3517 ssl_test_ticket_aead_open_soft_fail,
3518 ssl_test_ticket_aead_open_hard_fail)));
3519
David Benjamin96628432017-01-19 19:05:47 -05003520// TODO(davidben): Convert this file to GTest properly.
3521TEST(SSLTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -07003522 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003523 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003524 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3525 !TestSSL_SESSIONEncoding(kCustomSession) ||
3526 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3527 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3528 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3529 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003530 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07003531 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
3532 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
3533 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3534 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3535 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3536 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3537 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3538 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3539 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003540 // Test the padding extension at TLS 1.2.
3541 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3542 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3543 // will be no PSK binder after the padding extension.
3544 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3545 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3546 // will be a PSK binder after the padding extension.
3547 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003548 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003549 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003550 !ForEachVersion(TestOneSidedShutdown) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003551 !ForEachVersion(TestGetPeerCertificate) ||
3552 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003553 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003554 !ForEachVersion(TestSessionIDContext) ||
3555 !ForEachVersion(TestSessionTimeout) ||
3556 !ForEachVersion(TestSNICallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003557 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003558 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003559 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003560 !ForEachVersion(TestAutoChain) ||
3561 !ForEachVersion(TestSSLWriteRetry)) {
David Benjamin96628432017-01-19 19:05:47 -05003562 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003563 }
David Benjamin2e521212014-07-16 14:37:51 -04003564}