blob: 17ad4e403220db8cf1bb60c40bf5d76d11b994ca [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 Benjamin3cfeb952017-03-01 16:48:38 -05001860 // SSLv3 is off by default.
1861 !SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
David Benjamine4706902016-09-20 15:12:23 -04001862 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001863 !SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
David Benjaminafc64de2016-07-19 17:12:41 +02001864 return false;
1865 }
David Benjamin2dc02042016-09-19 19:57:37 -04001866
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001867 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001868 if (!ssl) {
1869 return false;
1870 }
1871 std::vector<uint8_t> client_hello;
1872 if (!GetClientHello(ssl.get(), &client_hello)) {
1873 return false;
1874 }
1875
1876 // Zero the client_random.
1877 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1878 1 + 3 + // handshake message header
1879 2; // client_version
1880 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1881 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1882 return false;
1883 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001884 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001885
1886 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001887 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001888 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1889 fprintf(stderr, "Got:\n\t");
1890 for (size_t i = 0; i < client_hello.size(); i++) {
1891 fprintf(stderr, "0x%02x, ", client_hello[i]);
1892 }
1893 fprintf(stderr, "\nWanted:\n\t");
1894 for (size_t i = 0; i < expected_len; i++) {
1895 fprintf(stderr, "0x%02x, ", expected[i]);
1896 }
1897 fprintf(stderr, "\n");
1898 return false;
1899 }
1900
1901 return true;
1902}
1903
1904// Tests that our ClientHellos do not change unexpectedly.
1905static bool TestClientHello() {
1906 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001907 0x16,
1908 0x03, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001909 0x00, 0x3b,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001910 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001911 0x00, 0x00, 0x37,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001912 0x03, 0x00,
1913 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1917 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001918 0x00, 0x10,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001919 0xc0, 0x09,
1920 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001921 0xc0, 0x0a,
1922 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001923 0x00, 0x2f,
1924 0x00, 0x35,
1925 0x00, 0x0a,
1926 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001927 };
1928 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1929 sizeof(kSSL3ClientHello))) {
1930 return false;
1931 }
1932
1933 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001934 0x16,
1935 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001936 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001937 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001938 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001939 0x03, 0x01,
1940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1944 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001945 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001946 0xc0, 0x09,
1947 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001948 0xc0, 0x0a,
1949 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001950 0x00, 0x2f,
1951 0x00, 0x35,
1952 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001953 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1954 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1955 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1956 };
1957 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1958 sizeof(kTLS1ClientHello))) {
1959 return false;
1960 }
1961
1962 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001963 0x16,
1964 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001965 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001966 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001967 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001968 0x03, 0x02,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001974 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001975 0xc0, 0x09,
1976 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001977 0xc0, 0x0a,
1978 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001979 0x00, 0x2f,
1980 0x00, 0x35,
1981 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001982 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1983 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1984 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1985 };
1986 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1987 sizeof(kTLS11ClientHello))) {
1988 return false;
1989 }
1990
David Benjamin3b584332017-01-24 22:47:18 -05001991 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
1992 // builds.
1993#if defined(BORINGSSL_ANDROID_SYSTEM)
1994 return true;
1995#endif
1996
David Benjaminafc64de2016-07-19 17:12:41 +02001997 static const uint8_t kTLS12ClientHello[] = {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001998 0x16,
1999 0x03, 0x01,
2000 0x00, 0x8e,
2001 0x01,
2002 0x00, 0x00, 0x8a,
2003 0x03, 0x03,
David Benjamin57e929f2016-08-30 00:30:38 -04002004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2007 0x00, 0x2a,
2008 0xcc, 0xa9,
2009 0xcc, 0xa8,
2010 0xc0, 0x2b,
2011 0xc0, 0x2f,
2012 0xc0, 0x2c,
2013 0xc0, 0x30,
2014 0xc0, 0x09,
2015 0xc0, 0x23,
2016 0xc0, 0x13,
2017 0xc0, 0x27,
2018 0xc0, 0x0a,
2019 0xc0, 0x24,
2020 0xc0, 0x14,
2021 0xc0, 0x28,
2022 0x00, 0x9c,
2023 0x00, 0x9d,
2024 0x00, 0x2f,
2025 0x00, 0x3c,
2026 0x00, 0x35,
2027 0x00, 0x3d,
2028 0x00, 0x0a,
2029 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2030 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
2031 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
2032 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2033 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02002034 };
2035 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
2036 sizeof(kTLS12ClientHello))) {
2037 return false;
2038 }
2039
2040 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2041 // implementation has settled enough that it won't change.
2042
2043 return true;
2044}
2045
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002046static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002047
2048static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2049 // Save the most recent session.
2050 g_last_session.reset(session);
2051 return 1;
2052}
2053
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002054static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04002055 SSL_CTX *server_ctx) {
2056 g_last_session = nullptr;
2057 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2058
2059 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002060 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002061 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2062 nullptr /* no session */)) {
2063 fprintf(stderr, "Failed to connect client and server.\n");
2064 return nullptr;
2065 }
2066
2067 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2068 SSL_read(client.get(), nullptr, 0);
2069
2070 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2071
2072 if (!g_last_session) {
2073 fprintf(stderr, "Client did not receive a session.\n");
2074 return nullptr;
2075 }
2076 return std::move(g_last_session);
2077}
2078
2079static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2080 SSL_SESSION *session,
2081 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002082 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002083 if (!ConnectClientAndServer(&client, &server, client_ctx,
2084 server_ctx, session)) {
2085 fprintf(stderr, "Failed to connect client and server.\n");
2086 return false;
2087 }
2088
2089 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2090 fprintf(stderr, "Client and server were inconsistent.\n");
2091 return false;
2092 }
2093
2094 bool was_reused = !!SSL_session_reused(client.get());
2095 if (was_reused != reused) {
2096 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
2097 was_reused ? "" : " not");
2098 return false;
2099 }
2100
2101 return true;
2102}
2103
David Benjamin3c51d9b2016-11-01 17:50:42 -04002104static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2105 SSL_CTX *server_ctx,
2106 SSL_SESSION *session) {
2107 g_last_session = nullptr;
2108 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2109
2110 bssl::UniquePtr<SSL> client, server;
2111 if (!ConnectClientAndServer(&client, &server, client_ctx,
2112 server_ctx, session)) {
2113 fprintf(stderr, "Failed to connect client and server.\n");
2114 return nullptr;
2115 }
2116
2117 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2118 fprintf(stderr, "Client and server were inconsistent.\n");
2119 return nullptr;
2120 }
2121
2122 if (!SSL_session_reused(client.get())) {
2123 fprintf(stderr, "Session was not reused.\n");
2124 return nullptr;
2125 }
2126
2127 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2128 SSL_read(client.get(), nullptr, 0);
2129
2130 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2131
2132 if (!g_last_session) {
2133 fprintf(stderr, "Client did not receive a renewed session.\n");
2134 return nullptr;
2135 }
2136 return std::move(g_last_session);
2137}
2138
David Benjamina933c382016-10-28 00:10:03 -04002139static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2140 static const uint8_t kContext[] = {3};
2141
2142 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2143 return SSL_TLSEXT_ERR_ALERT_FATAL;
2144 }
2145
2146 return SSL_TLSEXT_ERR_OK;
2147}
2148
David Benjamin0fef3052016-11-18 15:11:10 +09002149static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2150 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002151 bssl::UniquePtr<X509> cert = GetTestCertificate();
2152 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002153 if (!cert || !key) {
2154 return false;
2155 }
2156
2157 static const uint8_t kContext1[] = {1};
2158 static const uint8_t kContext2[] = {2};
2159
David Benjamin0fef3052016-11-18 15:11:10 +09002160 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2161 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2162 if (!server_ctx || !client_ctx ||
2163 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2164 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2165 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2166 sizeof(kContext1)) ||
2167 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2168 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2169 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2170 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2171 return false;
2172 }
David Benjamina20e5352016-08-02 19:09:41 -04002173
David Benjamin0fef3052016-11-18 15:11:10 +09002174 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2175 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002176
David Benjamin0fef3052016-11-18 15:11:10 +09002177 bssl::UniquePtr<SSL_SESSION> session =
2178 CreateClientSession(client_ctx.get(), server_ctx.get());
2179 if (!session) {
2180 fprintf(stderr, "Error getting session.\n");
2181 return false;
2182 }
David Benjamina20e5352016-08-02 19:09:41 -04002183
David Benjamin0fef3052016-11-18 15:11:10 +09002184 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2185 true /* expect session reused */)) {
2186 fprintf(stderr, "Error resuming session.\n");
2187 return false;
2188 }
David Benjamina20e5352016-08-02 19:09:41 -04002189
David Benjamin0fef3052016-11-18 15:11:10 +09002190 // Change the session ID context.
2191 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2192 sizeof(kContext2))) {
2193 return false;
2194 }
David Benjamina20e5352016-08-02 19:09:41 -04002195
David Benjamin0fef3052016-11-18 15:11:10 +09002196 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2197 false /* expect session not reused */)) {
2198 fprintf(stderr, "Error connecting with a different context.\n");
2199 return false;
2200 }
David Benjamina933c382016-10-28 00:10:03 -04002201
David Benjamin0fef3052016-11-18 15:11:10 +09002202 // Change the session ID context back and install an SNI callback to switch
2203 // it.
2204 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2205 sizeof(kContext1))) {
2206 return false;
2207 }
David Benjamina933c382016-10-28 00:10:03 -04002208
David Benjamin0fef3052016-11-18 15:11:10 +09002209 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2210 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002211
David Benjamin0fef3052016-11-18 15:11:10 +09002212 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2213 false /* expect session not reused */)) {
2214 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2215 return false;
2216 }
David Benjamina933c382016-10-28 00:10:03 -04002217
David Benjamin0fef3052016-11-18 15:11:10 +09002218 // Switch the session ID context with the early callback instead.
2219 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002220 SSL_CTX_set_select_certificate_cb(
2221 server_ctx.get(),
2222 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2223 static const uint8_t kContext[] = {3};
2224
2225 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2226 sizeof(kContext))) {
2227 return ssl_select_cert_error;
2228 }
2229
2230 return ssl_select_cert_success;
2231 });
David Benjamina933c382016-10-28 00:10:03 -04002232
David Benjamin0fef3052016-11-18 15:11:10 +09002233 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2234 false /* expect session not reused */)) {
2235 fprintf(stderr,
2236 "Error connecting with a context switch on early callback.\n");
2237 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002238 }
2239
2240 return true;
2241}
2242
David Benjamin721e8b72016-08-03 13:13:17 -04002243static timeval g_current_time;
2244
2245static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2246 *out_clock = g_current_time;
2247}
2248
David Benjamin17b30832017-01-28 14:00:32 -05002249static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2250 out_clock->tv_sec = 1000;
2251 out_clock->tv_usec = 0;
2252}
2253
David Benjamin3c51d9b2016-11-01 17:50:42 -04002254static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2255 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2256 int encrypt) {
2257 static const uint8_t kZeros[16] = {0};
2258
2259 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002260 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002261 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002262 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002263 return 0;
2264 }
2265
2266 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2267 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2268 return -1;
2269 }
2270
2271 // Returning two from the callback in decrypt mode renews the
2272 // session in TLS 1.2 and below.
2273 return encrypt ? 1 : 2;
2274}
2275
David Benjamin123db572016-11-03 16:59:25 -04002276static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002277 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2278 return false;
2279 }
2280
David Benjamin123db572016-11-03 16:59:25 -04002281 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2282 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2283 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2284
David Benjamin9b63f292016-11-15 00:44:05 -05002285#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2286 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002287 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002288#else
2289 static const uint8_t kZeros[16] = {0};
2290 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002291 bssl::ScopedEVP_CIPHER_CTX ctx;
2292 int len1, len2;
2293 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2294 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2295 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2296 return false;
2297 }
2298
2299 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002300#endif
David Benjamin123db572016-11-03 16:59:25 -04002301
Adam Langley46db7af2017-02-01 15:49:37 -08002302 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2303 if (!ssl_ctx) {
2304 return false;
2305 }
David Benjamin123db572016-11-03 16:59:25 -04002306 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002307 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002308 if (!server_session) {
2309 return false;
2310 }
2311
2312 *out = server_session->time;
2313 return true;
2314}
2315
David Benjamin0fef3052016-11-18 15:11:10 +09002316static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2317 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002318 bssl::UniquePtr<X509> cert = GetTestCertificate();
2319 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002320 if (!cert || !key) {
2321 return false;
2322 }
2323
David Benjamin0fef3052016-11-18 15:11:10 +09002324 for (bool server_test : std::vector<bool>{false, true}) {
David Benjamin17b30832017-01-28 14:00:32 -05002325 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002326 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002327
David Benjamin17b30832017-01-28 14:00:32 -05002328 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2329 // resumptions still perform ECDHE.
2330 const time_t timeout = version == TLS1_3_VERSION
2331 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2332 : SSL_DEFAULT_SESSION_TIMEOUT;
2333
David Benjamin0fef3052016-11-18 15:11:10 +09002334 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2335 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2336 if (!server_ctx || !client_ctx ||
2337 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2338 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2339 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2340 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2341 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2342 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2343 return false;
2344 }
2345
2346 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2347 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2348
David Benjamin17b30832017-01-28 14:00:32 -05002349 // Both client and server must enforce session timeouts. We configure the
2350 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002351 if (server_test) {
David Benjamin17b30832017-01-28 14:00:32 -05002352 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002353 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2354 } else {
2355 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
David Benjamin17b30832017-01-28 14:00:32 -05002356 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002357 }
2358
2359 // Configure a ticket callback which renews tickets.
2360 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2361
2362 bssl::UniquePtr<SSL_SESSION> session =
2363 CreateClientSession(client_ctx.get(), server_ctx.get());
2364 if (!session) {
2365 fprintf(stderr, "Error getting session.\n");
2366 return false;
2367 }
2368
2369 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002370 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002371
2372 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2373 true /* expect session reused */)) {
2374 fprintf(stderr, "Error resuming session.\n");
2375 return false;
2376 }
2377
2378 // Advance the clock one more second.
2379 g_current_time.tv_sec++;
2380
2381 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2382 false /* expect session not reused */)) {
2383 fprintf(stderr, "Error resuming session.\n");
2384 return false;
2385 }
2386
2387 // Rewind the clock to before the session was minted.
2388 g_current_time.tv_sec = kStartTime - 1;
2389
2390 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2391 false /* expect session not reused */)) {
2392 fprintf(stderr, "Error resuming session.\n");
2393 return false;
2394 }
2395
2396 // SSL 3.0 cannot renew sessions.
2397 if (version == SSL3_VERSION) {
2398 continue;
2399 }
2400
2401 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002402 time_t new_start_time = kStartTime + timeout - 10;
2403 g_current_time.tv_sec = new_start_time;
David Benjamin0fef3052016-11-18 15:11:10 +09002404 bssl::UniquePtr<SSL_SESSION> new_session =
2405 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2406 if (!new_session) {
2407 fprintf(stderr, "Error renewing session.\n");
2408 return false;
2409 }
2410
2411 // This new session is not the same object as before.
2412 if (session.get() == new_session.get()) {
2413 fprintf(stderr, "New and old sessions alias.\n");
2414 return false;
2415 }
2416
2417 // Check the sessions have timestamps measured from issuance.
2418 long session_time = 0;
2419 if (server_test) {
2420 if (!GetServerTicketTime(&session_time, new_session.get())) {
2421 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002422 return false;
2423 }
David Benjamin0fef3052016-11-18 15:11:10 +09002424 } else {
2425 session_time = new_session->time;
2426 }
David Benjamin721e8b72016-08-03 13:13:17 -04002427
David Benjamin0fef3052016-11-18 15:11:10 +09002428 if (session_time != g_current_time.tv_sec) {
2429 fprintf(stderr, "New session is not measured from issuance.\n");
2430 return false;
2431 }
David Benjamin721e8b72016-08-03 13:13:17 -04002432
David Benjamin17b30832017-01-28 14:00:32 -05002433 if (version == TLS1_3_VERSION) {
2434 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2435 // lifetime TLS 1.3.
2436 g_current_time.tv_sec = new_start_time + timeout - 1;
2437 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2438 new_session.get(),
2439 true /* expect session reused */)) {
2440 fprintf(stderr, "Error resuming renewed session.\n");
2441 return false;
2442 }
David Benjamin721e8b72016-08-03 13:13:17 -04002443
David Benjamin17b30832017-01-28 14:00:32 -05002444 // The new session expires after the new timeout.
2445 g_current_time.tv_sec = new_start_time + timeout + 1;
2446 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2447 new_session.get(),
2448 false /* expect session ot reused */)) {
2449 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2450 return false;
2451 }
2452
2453 // Renew the session until it begins just past the auth timeout.
2454 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2455 while (new_start_time < auth_end_time - 1000) {
2456 // Get as close as possible to target start time.
2457 new_start_time =
2458 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2459 g_current_time.tv_sec = new_start_time;
2460 new_session = ExpectSessionRenewed(client_ctx.get(), server_ctx.get(),
2461 new_session.get());
2462 if (!new_session) {
2463 fprintf(stderr, "Error renewing session.\n");
2464 return false;
2465 }
2466 }
2467
2468 // Now the session's lifetime is bound by the auth timeout.
2469 g_current_time.tv_sec = auth_end_time - 1;
2470 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2471 new_session.get(),
2472 true /* expect session reused */)) {
2473 fprintf(stderr, "Error resuming renewed session.\n");
2474 return false;
2475 }
2476
2477 g_current_time.tv_sec = auth_end_time + 1;
2478 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2479 new_session.get(),
2480 false /* expect session ot reused */)) {
2481 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2482 return false;
2483 }
2484 } else {
2485 // The new session is usable just before the old expiration.
2486 g_current_time.tv_sec = kStartTime + timeout - 1;
2487 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2488 new_session.get(),
2489 true /* expect session reused */)) {
2490 fprintf(stderr, "Error resuming renewed session.\n");
2491 return false;
2492 }
2493
2494 // Renewal does not extend the lifetime, so it is not usable beyond the
2495 // old expiration.
2496 g_current_time.tv_sec = kStartTime + timeout + 1;
2497 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2498 new_session.get(),
2499 false /* expect session not reused */)) {
2500 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2501 return false;
2502 }
David Benjamin1b22f852016-10-27 16:36:32 -04002503 }
David Benjamin721e8b72016-08-03 13:13:17 -04002504 }
2505
2506 return true;
2507}
2508
David Benjamin0fc37ef2016-08-17 15:29:46 -04002509static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2510 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2511 SSL_set_SSL_CTX(ssl, ctx);
2512 return SSL_TLSEXT_ERR_OK;
2513}
2514
David Benjamin0fef3052016-11-18 15:11:10 +09002515static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2516 uint16_t version) {
2517 // SSL 3.0 lacks extensions.
2518 if (version == SSL3_VERSION) {
2519 return true;
2520 }
2521
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002522 bssl::UniquePtr<X509> cert = GetTestCertificate();
2523 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2524 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2525 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002526 if (!cert || !key || !cert2 || !key2) {
2527 return false;
2528 }
2529
David Benjamin0fef3052016-11-18 15:11:10 +09002530 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2531 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002532
David Benjamin83a32122017-02-14 18:34:54 -05002533 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2534 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2535
David Benjamin0fef3052016-11-18 15:11:10 +09002536 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2537 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2538 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2539 if (!server_ctx || !server_ctx2 || !client_ctx ||
2540 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2541 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2542 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2543 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
David Benjamin83a32122017-02-14 18:34:54 -05002544 !SSL_CTX_set_signed_cert_timestamp_list(server_ctx2.get(), kSCTList,
2545 sizeof(kSCTList)) ||
2546 !SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2547 sizeof(kOCSPResponse)) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002548 // Historically signing preferences would be lost in some cases with the
2549 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2550 // this doesn't happen when |version| is TLS 1.2, configure the private
2551 // key to only sign SHA-256.
2552 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2553 1) ||
2554 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2555 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2556 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2557 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2558 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2559 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2560 return false;
2561 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002562
David Benjamin0fef3052016-11-18 15:11:10 +09002563 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2564 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002565
David Benjamin83a32122017-02-14 18:34:54 -05002566 SSL_CTX_enable_signed_cert_timestamps(client_ctx.get());
2567 SSL_CTX_enable_ocsp_stapling(client_ctx.get());
2568
David Benjamin0fef3052016-11-18 15:11:10 +09002569 bssl::UniquePtr<SSL> client, server;
2570 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2571 server_ctx.get(), nullptr)) {
2572 fprintf(stderr, "Handshake failed.\n");
2573 return false;
2574 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002575
David Benjamin0fef3052016-11-18 15:11:10 +09002576 // The client should have received |cert2|.
2577 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2578 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2579 fprintf(stderr, "Incorrect certificate received.\n");
2580 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002581 }
2582
David Benjamin83a32122017-02-14 18:34:54 -05002583 // The client should have received |server_ctx2|'s SCT list.
2584 const uint8_t *data;
2585 size_t len;
2586 SSL_get0_signed_cert_timestamp_list(client.get(), &data, &len);
2587 if (Bytes(kSCTList) != Bytes(data, len)) {
2588 fprintf(stderr, "Incorrect SCT list received.\n");
2589 return false;
2590 }
2591
2592 // The client should have received |server_ctx2|'s OCSP response.
2593 SSL_get0_ocsp_response(client.get(), &data, &len);
2594 if (Bytes(kOCSPResponse) != Bytes(data, len)) {
2595 fprintf(stderr, "Incorrect OCSP response received.\n");
2596 return false;
2597 }
2598
David Benjamin0fc37ef2016-08-17 15:29:46 -04002599 return true;
2600}
2601
David Benjaminf0d8e222017-02-04 10:58:26 -05002602// Test that the early callback can swap the maximum version.
2603TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002604 bssl::UniquePtr<X509> cert = GetTestCertificate();
2605 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2606 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2607 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002608 ASSERT_TRUE(cert);
2609 ASSERT_TRUE(key);
2610 ASSERT_TRUE(server_ctx);
2611 ASSERT_TRUE(client_ctx);
2612 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2613 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2614 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2615 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002616
David Benjaminf0d8e222017-02-04 10:58:26 -05002617 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002618 server_ctx.get(),
2619 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002620 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002621 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002622 }
2623
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002624 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002625 });
David Benjamin99620572016-08-30 00:35:36 -04002626
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002627 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002628 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2629 server_ctx.get(), nullptr));
2630 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002631}
2632
David Benjaminf0d8e222017-02-04 10:58:26 -05002633TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002634 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002635 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002636
David Benjaminf0d8e222017-02-04 10:58:26 -05002637 // Set valid TLS versions.
2638 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2639 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2640 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2641 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002642
David Benjaminf0d8e222017-02-04 10:58:26 -05002643 // Invalid TLS versions are rejected.
2644 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2645 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2646 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2647 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2648 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2649 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002650
David Benjaminf0d8e222017-02-04 10:58:26 -05002651 // Zero is the default version.
2652 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2653 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2654 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjamin3cfeb952017-03-01 16:48:38 -05002655 EXPECT_EQ(TLS1_VERSION, ctx->min_version);
2656
2657 // SSL 3.0 and TLS 1.3 are available, but not by default.
2658 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminf0d8e222017-02-04 10:58:26 -05002659 EXPECT_EQ(SSL3_VERSION, ctx->min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002660 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
2661 EXPECT_EQ(TLS1_3_VERSION, ctx->max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002662
David Benjamin2dc02042016-09-19 19:57:37 -04002663 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002664 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002665
David Benjaminf0d8e222017-02-04 10:58:26 -05002666 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2667 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2668 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2669 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002670
David Benjaminf0d8e222017-02-04 10:58:26 -05002671 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2672 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2673 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2674 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2675 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2676 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2677 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2678 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002679
David Benjaminf0d8e222017-02-04 10:58:26 -05002680 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2681 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2682 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2683 EXPECT_EQ(TLS1_1_VERSION, ctx->min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002684}
2685
David Benjamin458334a2016-12-15 13:53:25 -05002686static const char *GetVersionName(uint16_t version) {
2687 switch (version) {
2688 case SSL3_VERSION:
2689 return "SSLv3";
2690 case TLS1_VERSION:
2691 return "TLSv1";
2692 case TLS1_1_VERSION:
2693 return "TLSv1.1";
2694 case TLS1_2_VERSION:
2695 return "TLSv1.2";
2696 case TLS1_3_VERSION:
2697 return "TLSv1.3";
2698 case DTLS1_VERSION:
2699 return "DTLSv1";
2700 case DTLS1_2_VERSION:
2701 return "DTLSv1.2";
2702 default:
2703 return "???";
2704 }
2705}
2706
David Benjamin0fef3052016-11-18 15:11:10 +09002707static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2708 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002709 bssl::UniquePtr<X509> cert = GetTestCertificate();
2710 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2711 if (!cert || !key) {
2712 return false;
2713 }
2714
David Benjamin0fef3052016-11-18 15:11:10 +09002715 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2716 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2717 bssl::UniquePtr<SSL> client, server;
2718 if (!server_ctx || !client_ctx ||
2719 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2720 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2721 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2722 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2723 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2724 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2725 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2726 server_ctx.get(), nullptr /* no session */)) {
2727 fprintf(stderr, "Failed to connect.\n");
2728 return false;
2729 }
David Benjamincb18ac22016-09-27 14:09:15 -04002730
David Benjamin0fef3052016-11-18 15:11:10 +09002731 if (SSL_version(client.get()) != version ||
2732 SSL_version(server.get()) != version) {
2733 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2734 SSL_version(client.get()), SSL_version(server.get()), version);
2735 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002736 }
2737
David Benjamin458334a2016-12-15 13:53:25 -05002738 // Test the version name is reported as expected.
2739 const char *version_name = GetVersionName(version);
2740 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2741 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2742 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2743 SSL_get_version(client.get()), SSL_get_version(server.get()),
2744 version_name);
2745 return false;
2746 }
2747
2748 // Test SSL_SESSION reports the same name.
2749 const char *client_name =
2750 SSL_SESSION_get_version(SSL_get_session(client.get()));
2751 const char *server_name =
2752 SSL_SESSION_get_version(SSL_get_session(server.get()));
2753 if (strcmp(version_name, client_name) != 0 ||
2754 strcmp(version_name, server_name) != 0) {
2755 fprintf(stderr,
2756 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2757 client_name, server_name, version_name);
2758 return false;
2759 }
2760
David Benjamincb18ac22016-09-27 14:09:15 -04002761 return true;
2762}
2763
David Benjamin9ef31f02016-10-31 18:01:13 -04002764// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2765// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002766static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2767 uint16_t version) {
2768 // SSL 3.0 lacks extensions.
2769 if (version == SSL3_VERSION) {
2770 return true;
2771 }
2772
David Benjamin9ef31f02016-10-31 18:01:13 -04002773 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2774
2775 bssl::UniquePtr<X509> cert = GetTestCertificate();
2776 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2777 if (!cert || !key) {
2778 return false;
2779 }
2780
David Benjamin0fef3052016-11-18 15:11:10 +09002781 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2782 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2783 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2784 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2785 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2786 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2787 0) {
2788 return false;
2789 }
2790
2791 // The ALPN callback does not fail the handshake on error, so have the
2792 // callback write a boolean.
2793 std::pair<uint16_t, bool> callback_state(version, false);
2794 SSL_CTX_set_alpn_select_cb(
2795 ctx.get(),
2796 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2797 unsigned in_len, void *arg) -> int {
2798 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2799 if (SSL_get_pending_cipher(ssl) != nullptr &&
2800 SSL_version(ssl) == state->first) {
2801 state->second = true;
2802 }
2803 return SSL_TLSEXT_ERR_NOACK;
2804 },
2805 &callback_state);
2806
2807 bssl::UniquePtr<SSL> client, server;
2808 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2809 nullptr /* no session */)) {
2810 return false;
2811 }
2812
2813 if (!callback_state.second) {
2814 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2815 return false;
2816 }
2817
2818 return true;
2819}
2820
David Benjaminb79cc842016-12-07 15:57:14 -05002821static bool TestSSLClearSessionResumption(bool is_dtls,
2822 const SSL_METHOD *method,
2823 uint16_t version) {
2824 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2825 // API pattern.
2826 if (version == TLS1_3_VERSION) {
2827 return true;
2828 }
2829
2830 bssl::UniquePtr<X509> cert = GetTestCertificate();
2831 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2832 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2833 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2834 if (!cert || !key || !server_ctx || !client_ctx ||
2835 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2836 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2837 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2838 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2839 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2840 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2841 return false;
2842 }
2843
2844 // Connect a client and a server.
2845 bssl::UniquePtr<SSL> client, server;
2846 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2847 server_ctx.get(), nullptr /* no session */)) {
2848 return false;
2849 }
2850
2851 if (SSL_session_reused(client.get()) ||
2852 SSL_session_reused(server.get())) {
2853 fprintf(stderr, "Session unexpectedly reused.\n");
2854 return false;
2855 }
2856
2857 // Reset everything.
2858 if (!SSL_clear(client.get()) ||
2859 !SSL_clear(server.get())) {
2860 fprintf(stderr, "SSL_clear failed.\n");
2861 return false;
2862 }
2863
2864 // Attempt to connect a second time.
2865 if (!CompleteHandshakes(client.get(), server.get())) {
2866 fprintf(stderr, "Could not reuse SSL objects.\n");
2867 return false;
2868 }
2869
2870 // |SSL_clear| should implicitly offer the previous session to the server.
2871 if (!SSL_session_reused(client.get()) ||
2872 !SSL_session_reused(server.get())) {
2873 fprintf(stderr, "Session was not reused in second try.\n");
2874 return false;
2875 }
2876
2877 return true;
2878}
2879
David Benjamin1444c3a2016-12-20 17:23:11 -05002880static bool ChainsEqual(STACK_OF(X509) *chain,
2881 const std::vector<X509 *> &expected) {
2882 if (sk_X509_num(chain) != expected.size()) {
2883 return false;
2884 }
2885
2886 for (size_t i = 0; i < expected.size(); i++) {
2887 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2888 return false;
2889 }
2890 }
2891
2892 return true;
2893}
2894
2895static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2896 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002897 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2898 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2899 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2900 if (!cert || !intermediate || !key) {
2901 return false;
2902 }
2903
2904 // Configure both client and server to accept any certificate. Add
2905 // |intermediate| to the cert store.
2906 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2907 if (!ctx ||
2908 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2909 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2910 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2911 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2912 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2913 intermediate.get())) {
2914 return false;
2915 }
2916 SSL_CTX_set_verify(
2917 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2918 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2919
2920 // By default, the client and server should each only send the leaf.
2921 bssl::UniquePtr<SSL> client, server;
2922 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2923 nullptr /* no session */)) {
2924 return false;
2925 }
2926
2927 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2928 fprintf(stderr, "Client-received chain did not match.\n");
2929 return false;
2930 }
2931
2932 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2933 fprintf(stderr, "Server-received chain did not match.\n");
2934 return false;
2935 }
2936
2937 // If auto-chaining is enabled, then the intermediate is sent.
2938 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2939 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2940 nullptr /* no session */)) {
2941 return false;
2942 }
2943
2944 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2945 {cert.get(), intermediate.get()})) {
2946 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2947 return false;
2948 }
2949
2950 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2951 {cert.get(), intermediate.get()})) {
2952 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2953 return false;
2954 }
2955
2956 // Auto-chaining does not override explicitly-configured intermediates.
2957 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2958 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2959 nullptr /* no session */)) {
2960 return false;
2961 }
2962
2963 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2964 {cert.get(), cert.get()})) {
2965 fprintf(stderr,
2966 "Client-received chain did not match (auto-chaining, explicit "
2967 "intermediate).\n");
2968 return false;
2969 }
2970
2971 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2972 {cert.get(), cert.get()})) {
2973 fprintf(stderr,
2974 "Server-received chain did not match (auto-chaining, explicit "
2975 "intermediate).\n");
2976 return false;
2977 }
2978
2979 return true;
2980}
2981
David Benjamin48063c22017-01-01 23:56:36 -05002982static bool ExpectBadWriteRetry() {
2983 int err = ERR_get_error();
2984 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2985 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2986 char buf[ERR_ERROR_STRING_BUF_LEN];
2987 ERR_error_string_n(err, buf, sizeof(buf));
2988 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2989 return false;
2990 }
2991
2992 if (ERR_peek_error() != 0) {
2993 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2994 return false;
2995 }
2996
2997 return true;
2998}
2999
3000static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
3001 uint16_t version) {
3002 if (is_dtls) {
3003 return true;
3004 }
3005
3006 for (bool enable_partial_write : std::vector<bool>{false, true}) {
3007 // Connect a client and server.
3008 bssl::UniquePtr<X509> cert = GetTestCertificate();
3009 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3010 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
3011 bssl::UniquePtr<SSL> client, server;
3012 if (!cert || !key || !ctx ||
3013 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
3014 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
3015 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
3016 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
3017 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
3018 nullptr /* no session */)) {
3019 return false;
3020 }
3021
3022 if (enable_partial_write) {
3023 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
3024 }
3025
3026 // Write without reading until the buffer is full and we have an unfinished
3027 // write. Keep a count so we may reread it again later. "hello!" will be
3028 // written in two chunks, "hello" and "!".
3029 char data[] = "hello!";
3030 static const int kChunkLen = 5; // The length of "hello".
3031 unsigned count = 0;
3032 for (;;) {
3033 int ret = SSL_write(client.get(), data, kChunkLen);
3034 if (ret <= 0) {
3035 int err = SSL_get_error(client.get(), ret);
3036 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
3037 break;
3038 }
3039 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
3040 return false;
3041 }
3042
3043 if (ret != 5) {
3044 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
3045 return false;
3046 }
3047
3048 count++;
3049 }
3050
3051 // Retrying with the same parameters is legal.
3052 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
3053 SSL_ERROR_WANT_WRITE) {
3054 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3055 return false;
3056 }
3057
3058 // Retrying with the same buffer but shorter length is not legal.
3059 if (SSL_get_error(client.get(),
3060 SSL_write(client.get(), data, kChunkLen - 1)) !=
3061 SSL_ERROR_SSL ||
3062 !ExpectBadWriteRetry()) {
3063 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3064 return false;
3065 }
3066
3067 // Retrying with a different buffer pointer is not legal.
3068 char data2[] = "hello";
3069 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
3070 kChunkLen)) != SSL_ERROR_SSL ||
3071 !ExpectBadWriteRetry()) {
3072 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3073 return false;
3074 }
3075
3076 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
3077 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3078 if (SSL_get_error(client.get(),
3079 SSL_write(client.get(), data2, kChunkLen)) !=
3080 SSL_ERROR_WANT_WRITE) {
3081 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3082 return false;
3083 }
3084
3085 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
3086 if (SSL_get_error(client.get(),
3087 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3088 SSL_ERROR_SSL ||
3089 !ExpectBadWriteRetry()) {
3090 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3091 return false;
3092 }
3093
3094 // Retrying with a larger buffer is legal.
3095 if (SSL_get_error(client.get(),
3096 SSL_write(client.get(), data, kChunkLen + 1)) !=
3097 SSL_ERROR_WANT_WRITE) {
3098 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3099 return false;
3100 }
3101
3102 // Drain the buffer.
3103 char buf[20];
3104 for (unsigned i = 0; i < count; i++) {
3105 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3106 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3107 fprintf(stderr, "Failed to read initial records.\n");
3108 return false;
3109 }
3110 }
3111
3112 // Now that there is space, a retry with a larger buffer should flush the
3113 // pending record, skip over that many bytes of input (on assumption they
3114 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3115 // is set, this will complete in two steps.
3116 char data3[] = "_____!";
3117 if (enable_partial_write) {
3118 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3119 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3120 fprintf(stderr, "SSL_write retry failed.\n");
3121 return false;
3122 }
3123 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3124 fprintf(stderr, "SSL_write retry failed.\n");
3125 return false;
3126 }
3127
3128 // Check the last write was correct. The data will be spread over two
3129 // records, so SSL_read returns twice.
3130 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3131 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3132 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3133 buf[0] != '!') {
3134 fprintf(stderr, "Failed to read write retry.\n");
3135 return false;
3136 }
3137 }
3138
3139 return true;
3140}
3141
David Benjamin0fef3052016-11-18 15:11:10 +09003142static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3143 const SSL_METHOD *method,
3144 uint16_t version)) {
3145 static uint16_t kTLSVersions[] = {
David Benjamin3b584332017-01-24 22:47:18 -05003146 SSL3_VERSION,
3147 TLS1_VERSION,
3148 TLS1_1_VERSION,
3149 TLS1_2_VERSION,
3150// TLS 1.3 requires RSA-PSS, which is disabled for Android system builds.
3151#if !defined(BORINGSSL_ANDROID_SYSTEM)
3152 TLS1_3_VERSION,
3153#endif
David Benjamin0fef3052016-11-18 15:11:10 +09003154 };
3155
3156 static uint16_t kDTLSVersions[] = {
3157 DTLS1_VERSION, DTLS1_2_VERSION,
3158 };
3159
David Benjamin9ef31f02016-10-31 18:01:13 -04003160 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003161 if (!test_func(false, TLS_method(), version)) {
3162 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003163 return false;
3164 }
David Benjamin0fef3052016-11-18 15:11:10 +09003165 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003166
David Benjamin0fef3052016-11-18 15:11:10 +09003167 for (uint16_t version : kDTLSVersions) {
3168 if (!test_func(true, DTLS_method(), version)) {
3169 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003170 return false;
3171 }
3172 }
3173
3174 return true;
3175}
3176
Adam Langleye1e78132017-01-31 15:24:31 -08003177TEST(SSLTest, AddChainCertHack) {
3178 // Ensure that we don't accidently break the hack that we have in place to
3179 // keep curl and serf happy when they use an |X509| even after transfering
3180 // ownership.
3181
3182 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3183 ASSERT_TRUE(ctx);
3184 X509 *cert = GetTestCertificate().release();
3185 ASSERT_TRUE(cert);
3186 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3187
3188 // This should not trigger a use-after-free.
3189 X509_cmp(cert, cert);
3190}
3191
David Benjaminb2ff2622017-02-03 17:06:18 -05003192TEST(SSLTest, GetCertificate) {
3193 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3194 ASSERT_TRUE(ctx);
3195 bssl::UniquePtr<X509> cert = GetTestCertificate();
3196 ASSERT_TRUE(cert);
3197 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3198 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3199 ASSERT_TRUE(ssl);
3200
3201 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3202 ASSERT_TRUE(cert2);
3203 X509 *cert3 = SSL_get_certificate(ssl.get());
3204 ASSERT_TRUE(cert3);
3205
3206 // The old and new certificates must be identical.
3207 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3208 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3209
3210 uint8_t *der = nullptr;
3211 long der_len = i2d_X509(cert.get(), &der);
3212 ASSERT_LT(0, der_len);
3213 bssl::UniquePtr<uint8_t> free_der(der);
3214
3215 uint8_t *der2 = nullptr;
3216 long der2_len = i2d_X509(cert2, &der2);
3217 ASSERT_LT(0, der2_len);
3218 bssl::UniquePtr<uint8_t> free_der2(der2);
3219
3220 uint8_t *der3 = nullptr;
3221 long der3_len = i2d_X509(cert3, &der3);
3222 ASSERT_LT(0, der3_len);
3223 bssl::UniquePtr<uint8_t> free_der3(der3);
3224
3225 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003226 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3227 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003228}
3229
Adam Langleyd04ca952017-02-28 11:26:51 -08003230TEST(SSLTest, SetChainAndKeyMismatch) {
3231 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3232 ASSERT_TRUE(ctx);
3233
3234 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3235 ASSERT_TRUE(key);
3236 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3237 ASSERT_TRUE(leaf);
3238 std::vector<CRYPTO_BUFFER*> chain = {
3239 leaf.get(),
3240 };
3241
3242 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3243 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3244 key.get(), nullptr));
3245 ERR_clear_error();
3246}
3247
3248TEST(SSLTest, SetChainAndKey) {
3249 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3250 ASSERT_TRUE(client_ctx);
3251 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3252 ASSERT_TRUE(server_ctx);
3253
3254 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3255 ASSERT_TRUE(key);
3256 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3257 ASSERT_TRUE(leaf);
3258 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3259 GetChainTestIntermediateBuffer();
3260 ASSERT_TRUE(intermediate);
3261 std::vector<CRYPTO_BUFFER*> chain = {
3262 leaf.get(), intermediate.get(),
3263 };
3264 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3265 chain.size(), key.get(), nullptr));
3266
3267 SSL_CTX_i_promise_to_verify_certs_after_the_handshake(client_ctx.get());
3268
3269 bssl::UniquePtr<SSL> client, server;
3270 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3271 server_ctx.get(),
3272 nullptr /* no session */));
3273}
3274
David Benjamin91222b82017-03-09 20:10:56 -05003275// Configuring the empty cipher list, though an error, should still modify the
3276// configuration.
3277TEST(SSLTest, EmptyCipherList) {
3278 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3279 ASSERT_TRUE(ctx);
3280
3281 // Initially, the cipher list is not empty.
3282 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3283
3284 // Configuring the empty cipher list fails.
3285 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3286 ERR_clear_error();
3287
3288 // But the cipher list is still updated to empty.
3289 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3290}
3291
Adam Langley4c341d02017-03-08 19:33:21 -08003292// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3293// test |SSL_TICKET_AEAD_METHOD| can fail.
3294enum ssl_test_ticket_aead_failure_mode {
3295 ssl_test_ticket_aead_ok = 0,
3296 ssl_test_ticket_aead_seal_fail,
3297 ssl_test_ticket_aead_open_soft_fail,
3298 ssl_test_ticket_aead_open_hard_fail,
3299};
3300
3301struct ssl_test_ticket_aead_state {
3302 unsigned retry_count;
3303 ssl_test_ticket_aead_failure_mode failure_mode;
3304};
3305
3306static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3307 const CRYPTO_EX_DATA *from,
3308 void **from_d, int index,
3309 long argl, void *argp) {
3310 abort();
3311}
3312
3313static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3314 CRYPTO_EX_DATA *ad, int index,
3315 long argl, void *argp) {
3316 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3317 if (state == nullptr) {
3318 return;
3319 }
3320
3321 OPENSSL_free(state);
3322}
3323
3324static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3325static int g_ssl_test_ticket_aead_ex_index;
3326
3327static int ssl_test_ticket_aead_get_ex_index() {
3328 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3329 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3330 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3331 ssl_test_ticket_aead_ex_index_free);
3332 });
3333 return g_ssl_test_ticket_aead_ex_index;
3334}
3335
3336static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3337 return 1;
3338}
3339
3340static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3341 size_t max_out_len, const uint8_t *in,
3342 size_t in_len) {
3343 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3344 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3345
3346 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3347 max_out_len < in_len + 1) {
3348 return 0;
3349 }
3350
3351 OPENSSL_memmove(out, in, in_len);
3352 out[in_len] = 0xff;
3353 *out_len = in_len + 1;
3354
3355 return 1;
3356}
3357
3358static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3359 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3360 const uint8_t *in, size_t in_len) {
3361 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3362 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3363
3364 if (state->retry_count > 0) {
3365 state->retry_count--;
3366 return ssl_ticket_aead_retry;
3367 }
3368
3369 switch (state->failure_mode) {
3370 case ssl_test_ticket_aead_ok:
3371 break;
3372 case ssl_test_ticket_aead_seal_fail:
3373 // If |seal| failed then there shouldn't be any ticket to try and
3374 // decrypt.
3375 abort();
3376 break;
3377 case ssl_test_ticket_aead_open_soft_fail:
3378 return ssl_ticket_aead_ignore_ticket;
3379 case ssl_test_ticket_aead_open_hard_fail:
3380 return ssl_ticket_aead_error;
3381 }
3382
3383 if (in_len == 0 || in[in_len - 1] != 0xff) {
3384 return ssl_ticket_aead_ignore_ticket;
3385 }
3386
3387 if (max_out_len < in_len - 1) {
3388 return ssl_ticket_aead_error;
3389 }
3390
3391 OPENSSL_memmove(out, in, in_len - 1);
3392 *out_len = in_len - 1;
3393 return ssl_ticket_aead_success;
3394}
3395
3396static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3397 ssl_test_ticket_aead_max_overhead,
3398 ssl_test_ticket_aead_seal,
3399 ssl_test_ticket_aead_open,
3400};
3401
3402static void ConnectClientAndServerWithTicketMethod(
3403 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3404 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3405 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3406 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3407 ASSERT_TRUE(client);
3408 ASSERT_TRUE(server);
3409 SSL_set_connect_state(client.get());
3410 SSL_set_accept_state(server.get());
3411
3412 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3413 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3414 ASSERT_TRUE(state);
3415 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3416 state->retry_count = retry_count;
3417 state->failure_mode = failure_mode;
3418
3419 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3420 state));
3421
3422 SSL_set_session(client.get(), session);
3423
3424 BIO *bio1, *bio2;
3425 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3426
3427 // SSL_set_bio takes ownership.
3428 SSL_set_bio(client.get(), bio1, bio1);
3429 SSL_set_bio(server.get(), bio2, bio2);
3430
3431 if (CompleteHandshakes(client.get(), server.get())) {
3432 *out_client = std::move(client);
3433 *out_server = std::move(server);
3434 } else {
3435 out_client->reset();
3436 out_server->reset();
3437 }
3438}
3439
3440class TicketAEADMethodTest
3441 : public ::testing::TestWithParam<testing::tuple<
3442 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3443
3444TEST_P(TicketAEADMethodTest, Resume) {
3445 bssl::UniquePtr<X509> cert = GetTestCertificate();
3446 ASSERT_TRUE(cert);
3447 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3448 ASSERT_TRUE(key);
3449
3450 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3451 ASSERT_TRUE(server_ctx);
3452 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3453 ASSERT_TRUE(client_ctx);
3454
3455 const uint16_t version = testing::get<0>(GetParam());
3456 const unsigned retry_count = testing::get<1>(GetParam());
3457 const ssl_test_ticket_aead_failure_mode failure_mode =
3458 testing::get<2>(GetParam());
3459
3460 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3461 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3462 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3463 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3464 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3465 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3466
3467 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3468 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3469 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3470 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003471 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003472
3473 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3474
3475 bssl::UniquePtr<SSL> client, server;
3476 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3477 server_ctx.get(), retry_count,
3478 failure_mode, nullptr);
3479 switch (failure_mode) {
3480 case ssl_test_ticket_aead_ok:
3481 case ssl_test_ticket_aead_open_hard_fail:
3482 case ssl_test_ticket_aead_open_soft_fail:
3483 ASSERT_TRUE(client);
3484 break;
3485 case ssl_test_ticket_aead_seal_fail:
3486 EXPECT_FALSE(client);
3487 return;
3488 }
3489 EXPECT_FALSE(SSL_session_reused(client.get()));
3490 EXPECT_FALSE(SSL_session_reused(server.get()));
3491
David Benjamin707af292017-03-10 17:47:18 -05003492 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3493 SSL_read(client.get(), nullptr, 0);
3494
3495 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003496 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3497 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003498 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003499 switch (failure_mode) {
3500 case ssl_test_ticket_aead_ok:
3501 ASSERT_TRUE(client);
3502 EXPECT_TRUE(SSL_session_reused(client.get()));
3503 EXPECT_TRUE(SSL_session_reused(server.get()));
3504 break;
3505 case ssl_test_ticket_aead_seal_fail:
3506 abort();
3507 break;
3508 case ssl_test_ticket_aead_open_hard_fail:
3509 EXPECT_FALSE(client);
3510 break;
3511 case ssl_test_ticket_aead_open_soft_fail:
3512 ASSERT_TRUE(client);
3513 EXPECT_FALSE(SSL_session_reused(client.get()));
3514 EXPECT_FALSE(SSL_session_reused(server.get()));
3515 }
3516}
3517
3518INSTANTIATE_TEST_CASE_P(
3519 TicketAEADMethodTests, TicketAEADMethodTest,
3520 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003521 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003522 testing::Values(0, 1, 2),
3523 testing::Values(ssl_test_ticket_aead_ok,
3524 ssl_test_ticket_aead_seal_fail,
3525 ssl_test_ticket_aead_open_soft_fail,
3526 ssl_test_ticket_aead_open_hard_fail)));
3527
David Benjamin3cfeb952017-03-01 16:48:38 -05003528TEST(SSLTest, SSL3Method) {
3529 bssl::UniquePtr<X509> cert = GetTestCertificate();
3530 ASSERT_TRUE(cert);
3531
3532 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3533 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3534 ASSERT_TRUE(ssl3_ctx);
3535 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3536 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3537 EXPECT_TRUE(ssl);
3538
3539 // Create a normal TLS context to test against.
3540 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3541 ASSERT_TRUE(tls_ctx);
3542 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3543
3544 // However, handshaking an SSLv3_method server should fail to resolve the
3545 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3546 // way to enable SSL 3.0.
3547 bssl::UniquePtr<SSL> client, server;
3548 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
3549 ssl3_ctx.get(),
3550 nullptr /* no session */));
3551 uint32_t err = ERR_get_error();
3552 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3553 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3554
3555 // Likewise for SSLv3_method clients.
3556 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
3557 tls_ctx.get(),
3558 nullptr /* no session */));
3559 err = ERR_get_error();
3560 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3561 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3562}
3563
David Benjamin96628432017-01-19 19:05:47 -05003564// TODO(davidben): Convert this file to GTest properly.
3565TEST(SSLTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -07003566 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003567 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003568 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3569 !TestSSL_SESSIONEncoding(kCustomSession) ||
3570 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3571 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3572 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3573 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003574 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003575 !TestDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003576 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3577 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3578 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3579 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3580 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3581 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3582 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003583 // Test the padding extension at TLS 1.2.
3584 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3585 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3586 // will be no PSK binder after the padding extension.
3587 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3588 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3589 // will be a PSK binder after the padding extension.
3590 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003591 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003592 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003593 !ForEachVersion(TestOneSidedShutdown) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003594 !ForEachVersion(TestGetPeerCertificate) ||
3595 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003596 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003597 !ForEachVersion(TestSessionIDContext) ||
3598 !ForEachVersion(TestSessionTimeout) ||
3599 !ForEachVersion(TestSNICallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003600 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003601 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003602 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003603 !ForEachVersion(TestAutoChain) ||
3604 !ForEachVersion(TestSSLWriteRetry)) {
David Benjamin96628432017-01-19 19:05:47 -05003605 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003606 }
David Benjamin2e521212014-07-16 14:37:51 -04003607}