blob: d6edcfe1ffa9e6ee4e481b25e36b9ca12d217b01 [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>
Steven Valdezc8e0f902018-07-14 11:23:01 -040020#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040021#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050022#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040023#include <vector>
24
David Benjamin96628432017-01-19 19:05:47 -050025#include <gtest/gtest.h>
26
David Benjamin0e7dbd52019-05-15 16:01:18 -040027#include <openssl/aead.h>
David Benjamin751e8892014-10-19 00:59:36 -040028#include <openssl/base64.h>
David Benjamine9c5d722021-06-09 17:43:16 -040029#include <openssl/bytestring.h>
David Benjamin751e8892014-10-19 00:59:36 -040030#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040032#include <openssl/crypto.h>
Daniel McArdle00e434d2021-02-18 11:47:18 -050033#include <openssl/curve25519.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/hmac.h>
David Benjaminc890ae52021-06-06 13:32:29 -040036#include <openssl/hpke.h>
David Benjaminde942382016-02-11 12:02:01 -050037#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040038#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040039#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040040#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050041#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040042
Steven Valdez87eab492016-06-27 16:34:59 -040043#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040044#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020045#include "../crypto/test/test_util.h"
46
David Benjamin721e8b72016-08-03 13:13:17 -040047#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040048// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040049OPENSSL_MSVC_PRAGMA(warning(push, 3))
50#include <winsock2.h>
51OPENSSL_MSVC_PRAGMA(warning(pop))
52#else
53#include <sys/time.h>
54#endif
55
David Benjamin5b33eff2018-09-22 16:52:48 -070056#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040057#include <thread>
58#endif
59
David Benjamin1d77e562015-03-22 17:22:08 -040060
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070061BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070062
63namespace {
64
Martin Kreichgauer1a663262017-08-16 14:54:04 -070065#define TRACED_CALL(code) \
66 do { \
67 SCOPED_TRACE("<- called from here"); \
68 code; \
69 if (::testing::Test::HasFatalFailure()) { \
70 return; \
71 } \
72 } while (false)
73
Martin Kreichgauer72912d22017-08-04 12:06:43 -070074struct VersionParam {
75 uint16_t version;
76 enum { is_tls, is_dtls } ssl_method;
77 const char name[8];
78};
79
80static const size_t kTicketKeyLen = 48;
81
82static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070083 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
84 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
85 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070086 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070087 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
88 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
89};
90
David Benjamin1d77e562015-03-22 17:22:08 -040091struct ExpectedCipher {
92 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040093 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040094};
David Benjaminbb0a17c2014-09-20 15:35:39 -040095
David Benjamin1d77e562015-03-22 17:22:08 -040096struct CipherTest {
97 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040098 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050099 // The list of expected ciphers, in order.
100 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800101 // True if this cipher list should fail in strict mode.
102 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400103};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400104
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100105struct CurveTest {
106 // The rule string to apply.
107 const char *rule;
108 // The list of expected curves, in order.
109 std::vector<uint16_t> expected;
110};
111
Steven Valdezc8e0f902018-07-14 11:23:01 -0400112template <typename T>
113class UnownedSSLExData {
114 public:
115 UnownedSSLExData() {
116 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
117 }
118
119 T *Get(const SSL *ssl) {
120 return index_ < 0 ? nullptr
121 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
122 }
123
124 bool Set(SSL *ssl, T *t) {
125 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
126 }
127
128 private:
129 int index_;
130};
131
David Benjaminfb974e62015-12-16 19:34:22 -0500132static const CipherTest kCipherTests[] = {
133 // Selecting individual ciphers should work.
134 {
135 "ECDHE-ECDSA-CHACHA20-POLY1305:"
136 "ECDHE-RSA-CHACHA20-POLY1305:"
137 "ECDHE-ECDSA-AES128-GCM-SHA256:"
138 "ECDHE-RSA-AES128-GCM-SHA256",
139 {
140 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500141 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
144 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800145 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500146 },
147 // + reorders selected ciphers to the end, keeping their relative order.
148 {
149 "ECDHE-ECDSA-CHACHA20-POLY1305:"
150 "ECDHE-RSA-CHACHA20-POLY1305:"
151 "ECDHE-ECDSA-AES128-GCM-SHA256:"
152 "ECDHE-RSA-AES128-GCM-SHA256:"
153 "+aRSA",
154 {
155 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500156 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
157 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500158 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
159 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800160 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500161 },
162 // ! banishes ciphers from future selections.
163 {
164 "!aRSA:"
165 "ECDHE-ECDSA-CHACHA20-POLY1305:"
166 "ECDHE-RSA-CHACHA20-POLY1305:"
167 "ECDHE-ECDSA-AES128-GCM-SHA256:"
168 "ECDHE-RSA-AES128-GCM-SHA256",
169 {
170 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500171 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
172 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800173 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500174 },
175 // Multiple masks can be ANDed in a single rule.
176 {
177 "kRSA+AESGCM+AES128",
178 {
179 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
180 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800181 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500182 },
183 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700184 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500185 // ECDHE_RSA.
186 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700187 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700188 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500189 "AESGCM+AES128+aRSA",
190 {
191 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800194 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500195 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800196 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500197 {
198 "ECDHE-ECDSA-CHACHA20-POLY1305:"
199 "ECDHE-RSA-CHACHA20-POLY1305:"
200 "ECDHE-ECDSA-AES128-GCM-SHA256:"
201 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800202 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500203 {
204 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500205 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500206 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
207 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
208 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800209 true,
210 },
211 // Unknown selectors are no-ops, except in strict mode.
212 {
213 "ECDHE-ECDSA-CHACHA20-POLY1305:"
214 "ECDHE-RSA-CHACHA20-POLY1305:"
215 "ECDHE-ECDSA-AES128-GCM-SHA256:"
216 "ECDHE-RSA-AES128-GCM-SHA256:"
217 "-BOGUS2:+BOGUS3:!BOGUS4",
218 {
219 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
221 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
222 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
223 },
224 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500225 },
226 // Square brackets specify equi-preference groups.
227 {
228 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
229 "[ECDHE-RSA-CHACHA20-POLY1305]:"
230 "ECDHE-RSA-AES128-GCM-SHA256",
231 {
232 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500233 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800234 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500235 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
236 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800237 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500238 },
David Benjamin6fff3862017-06-21 21:07:04 -0400239 // Standard names may be used instead of OpenSSL names.
240 {
241 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400242 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400243 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
244 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
245 {
246 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
247 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
248 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
249 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
250 },
251 false,
252 },
David Benjaminfb974e62015-12-16 19:34:22 -0500253 // @STRENGTH performs a stable strength-sort of the selected ciphers and
254 // only the selected ciphers.
255 {
256 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700257 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400258 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500259 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700260 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500261 // Select ECDHE ones and sort them by strength. Ties should resolve
262 // based on the order above.
263 "kECDHE:@STRENGTH:-ALL:"
264 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
265 // by strength. Then RSA, backwards by strength.
266 "aRSA",
267 {
268 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
269 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500270 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500271 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
272 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
273 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800274 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500275 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400276 // Additional masks after @STRENGTH get silently discarded.
277 //
278 // TODO(davidben): Make this an error. If not silently discarded, they get
279 // interpreted as + opcodes which are very different.
280 {
281 "ECDHE-RSA-AES128-GCM-SHA256:"
282 "ECDHE-RSA-AES256-GCM-SHA384:"
283 "@STRENGTH+AES256",
284 {
285 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
286 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
287 },
288 false,
289 },
290 {
291 "ECDHE-RSA-AES128-GCM-SHA256:"
292 "ECDHE-RSA-AES256-GCM-SHA384:"
293 "@STRENGTH+AES256:"
294 "ECDHE-RSA-CHACHA20-POLY1305",
295 {
296 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
297 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
298 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
299 },
300 false,
301 },
David Benjaminfb974e62015-12-16 19:34:22 -0500302 // Exact ciphers may not be used in multi-part rules; they are treated
303 // as unknown aliases.
304 {
305 "ECDHE-ECDSA-AES128-GCM-SHA256:"
306 "ECDHE-RSA-AES128-GCM-SHA256:"
307 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
308 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
309 {
310 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
311 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
312 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800313 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500314 },
315 // SSLv3 matches everything that existed before TLS 1.2.
316 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400317 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500318 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400319 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500320 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800321 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500322 },
323 // TLSv1.2 matches everything added in TLS 1.2.
324 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400325 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500326 {
327 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
328 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800329 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500330 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800331 // The two directives have no intersection. But each component is valid, so
332 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500333 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400334 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500335 {
336 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400337 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500338 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800339 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500340 },
Adam Langley22df6912017-07-25 12:27:37 -0700341 // Spaces, semi-colons and commas are separators.
342 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400343 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700344 {
345 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400346 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700347 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400348 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700349 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
350 },
351 // …but not in strict mode.
352 true,
353 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354};
355
356static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400357 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400358 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
359 "RSA]",
360 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400361 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400363 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400365 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400366 "",
367 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400368 // COMPLEMENTOFDEFAULT is empty.
369 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400370 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400371 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400372 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400373 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
374 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
375 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
376 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700377 // Opcode supplied, but missing selector.
378 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700379 // Spaces are forbidden in equal-preference groups.
380 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400381};
382
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700383static const char *kMustNotIncludeNull[] = {
384 "ALL",
385 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500386 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700387 "FIPS",
388 "SHA",
389 "SHA1",
390 "RSA",
391 "SSLv3",
392 "TLSv1",
393 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700394};
395
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100396static const CurveTest kCurveTests[] = {
397 {
398 "P-256",
399 { SSL_CURVE_SECP256R1 },
400 },
401 {
Adam Langley7b935932018-11-12 13:53:42 -0800402 "P-256:CECPQ2",
403 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
404 },
405
406 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100407 "P-256:P-384:P-521:X25519",
408 {
409 SSL_CURVE_SECP256R1,
410 SSL_CURVE_SECP384R1,
411 SSL_CURVE_SECP521R1,
412 SSL_CURVE_X25519,
413 },
414 },
David Benjamin6dda1662017-11-02 20:44:26 -0400415 {
416 "prime256v1:secp384r1:secp521r1:x25519",
417 {
418 SSL_CURVE_SECP256R1,
419 SSL_CURVE_SECP384R1,
420 SSL_CURVE_SECP521R1,
421 SSL_CURVE_X25519,
422 },
423 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100424};
425
426static const char *kBadCurvesLists[] = {
427 "",
428 ":",
429 "::",
430 "P-256::X25519",
431 "RSA:P-256",
432 "P-256:RSA",
433 "X25519:P-256:",
434 ":X25519:P-256",
435};
436
David Benjamin70dbf042017-08-08 18:51:37 -0400437static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400438 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400439 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400440 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
441 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
442 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
443 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400444 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400445 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400446 }
David Benjamine11726a2017-04-23 12:14:28 -0400447 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400449 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400450 }
David Benjamine11726a2017-04-23 12:14:28 -0400451 ret += SSL_CIPHER_get_name(cipher);
452 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400453 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400454 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400455 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400456 }
457 }
David Benjamine11726a2017-04-23 12:14:28 -0400458 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400459}
460
David Benjamin70dbf042017-08-08 18:51:37 -0400461static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400462 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400463 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
464 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400465 return false;
David Benjamin65226252015-02-05 16:49:47 -0500466 }
467
David Benjamine11726a2017-04-23 12:14:28 -0400468 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400469 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400470 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400471 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400472 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400473 }
474 }
475
David Benjamin1d77e562015-03-22 17:22:08 -0400476 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400477}
478
Daniel McArdleff746c12019-09-16 12:35:05 -0400479TEST(GrowableArrayTest, Resize) {
480 GrowableArray<size_t> array;
481 ASSERT_TRUE(array.empty());
482 EXPECT_EQ(array.size(), 0u);
483
484 ASSERT_TRUE(array.Push(42));
485 ASSERT_TRUE(!array.empty());
486 EXPECT_EQ(array.size(), 1u);
487
488 // Force a resize operation to occur
489 for (size_t i = 0; i < 16; i++) {
490 ASSERT_TRUE(array.Push(i + 1));
491 }
492
493 EXPECT_EQ(array.size(), 17u);
494
495 // Verify that expected values are still contained in array
496 for (size_t i = 0; i < array.size(); i++) {
497 EXPECT_EQ(array[i], i == 0 ? 42 : i);
498 }
499}
500
501TEST(GrowableArrayTest, MoveConstructor) {
502 GrowableArray<size_t> array;
503 for (size_t i = 0; i < 100; i++) {
504 ASSERT_TRUE(array.Push(i));
505 }
506
507 GrowableArray<size_t> array_moved(std::move(array));
508 for (size_t i = 0; i < 100; i++) {
509 EXPECT_EQ(array_moved[i], i);
510 }
511}
512
513TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
514 // Representative example of a struct that contains a GrowableArray.
515 struct TagAndArray {
516 size_t tag;
517 GrowableArray<size_t> array;
518 };
519
520 GrowableArray<TagAndArray> array;
521 for (size_t i = 0; i < 100; i++) {
522 TagAndArray elem;
523 elem.tag = i;
524 for (size_t j = 0; j < i; j++) {
525 ASSERT_TRUE(elem.array.Push(j));
526 }
527 ASSERT_TRUE(array.Push(std::move(elem)));
528 }
529 EXPECT_EQ(array.size(), static_cast<size_t>(100));
530
531 GrowableArray<TagAndArray> array_moved(std::move(array));
532 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
533 size_t count = 0;
534 for (const TagAndArray &elem : array_moved) {
535 // Test the square bracket operator returns the same value as iteration.
536 EXPECT_EQ(&elem, &array_moved[count]);
537
538 EXPECT_EQ(elem.tag, count);
539 EXPECT_EQ(elem.array.size(), count);
540 for (size_t j = 0; j < count; j++) {
541 EXPECT_EQ(elem.array[j], j);
542 }
543 count++;
544 }
545}
546
David Benjamine11726a2017-04-23 12:14:28 -0400547TEST(SSLTest, CipherRules) {
548 for (const CipherTest &t : kCipherTests) {
549 SCOPED_TRACE(t.rule);
550 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
551 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700552
David Benjamine11726a2017-04-23 12:14:28 -0400553 // Test lax mode.
554 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400555 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400556 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400557 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400558
559 // Test strict mode.
560 if (t.strict_fail) {
561 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
562 } else {
563 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400564 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400565 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400566 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400567 }
568 }
569
David Benjaminfb974e62015-12-16 19:34:22 -0500570 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400571 SCOPED_TRACE(rule);
572 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
573 ASSERT_TRUE(ctx);
574
575 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400576 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400577 }
578
David Benjaminfb974e62015-12-16 19:34:22 -0500579 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400580 SCOPED_TRACE(rule);
581 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
582 ASSERT_TRUE(ctx);
583
584 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400585 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700586 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700587 }
588 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400589}
David Benjamin2e521212014-07-16 14:37:51 -0400590
David Benjamine11726a2017-04-23 12:14:28 -0400591TEST(SSLTest, CurveRules) {
592 for (const CurveTest &t : kCurveTests) {
593 SCOPED_TRACE(t.rule);
594 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
595 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100596
David Benjamine11726a2017-04-23 12:14:28 -0400597 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400598 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400599 for (size_t i = 0; i < t.expected.size(); i++) {
600 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100601 }
602 }
603
604 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400605 SCOPED_TRACE(rule);
606 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
607 ASSERT_TRUE(ctx);
608
609 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100610 ERR_clear_error();
611 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100612}
613
Adam Langley364f7a62016-12-12 10:51:00 -0800614// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700615static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800616 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700617 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
618 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
619 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
620 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
621 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
622 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
623 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
624 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
625 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
626 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
627 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
628 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
629 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
630 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
631 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
632 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
633 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
634 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
635 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
636 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
637 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
638 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
639 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
640 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
641 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
642 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
643 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
644 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
645 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800646 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700647
648// kCustomSession is a custom serialized SSL_SESSION generated by
649// filling in missing fields from |kOpenSSLSession|. This includes
650// providing |peer_sha256|, so |peer| is not serialized.
651static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400652 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700653 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400654 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
655 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
656 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
657 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
658 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
659 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700660
661// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
662static const char kBoringSSLSession[] =
663 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
664 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
665 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
666 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
667 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
668 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
669 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
670 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
671 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
672 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
673 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
674 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
675 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
676 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
677 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
678 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
679 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
680 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
681 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
682 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
683 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
684 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
685 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
686 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
687 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
688 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
689 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
690 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
691 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
692 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
693 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
694 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
695 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
696 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
697 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
698 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
699 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
700 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
701 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
702 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
703 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
704 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
705 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
706 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
707 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
708 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
709 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
710 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
711 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
712 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
713 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
714 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
715 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
716 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
717 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
718 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
719 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
720 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
721 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
722 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
723 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
724 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
725 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
726 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
727 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
728 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
729 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
730 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
731 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
732 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
733 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
734 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
735 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
736 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
737 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
738 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
739 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
740 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
741 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
742 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
743 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
744 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
745 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
746 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
747 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
748 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
749 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
750 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
751 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
752 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
753 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
754 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
755 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
756 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
757 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
758
759// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400760// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700761static const char kBadSessionExtraField[] =
762 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
763 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
764 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
765 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
766 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
767 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
768 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400769 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700770
771// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
772// the version of |kCustomSession| with 2.
773static const char kBadSessionVersion[] =
774 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
775 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
776 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
777 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
778 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
779 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
780 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
781 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
782
783// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
784// appended.
785static const char kBadSessionTrailingData[] =
786 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
787 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
788 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
789 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
790 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
791 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
792 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
793 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
794
David Benjamin1d77e562015-03-22 17:22:08 -0400795static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400796 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400797 if (!EVP_DecodedLength(&len, strlen(in))) {
798 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400799 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400800 }
801
David Benjamin1d77e562015-03-22 17:22:08 -0400802 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800803 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400804 strlen(in))) {
805 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400806 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400807 }
David Benjamin1d77e562015-03-22 17:22:08 -0400808 out->resize(len);
809 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400810}
811
David Benjamina486c6c2019-03-28 18:32:38 -0500812TEST(SSLTest, SessionEncoding) {
813 for (const char *input_b64 : {
814 kOpenSSLSession,
815 kCustomSession,
816 kBoringSSLSession,
817 }) {
818 SCOPED_TRACE(std::string(input_b64));
819 // Decode the input.
820 std::vector<uint8_t> input;
821 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400822
David Benjamina486c6c2019-03-28 18:32:38 -0500823 // Verify the SSL_SESSION decodes.
824 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
825 ASSERT_TRUE(ssl_ctx);
826 bssl::UniquePtr<SSL_SESSION> session(
827 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
828 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
829
830 // Verify the SSL_SESSION encoding round-trips.
831 size_t encoded_len;
832 bssl::UniquePtr<uint8_t> encoded;
833 uint8_t *encoded_raw;
834 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
835 << "SSL_SESSION_to_bytes failed";
836 encoded.reset(encoded_raw);
837 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
838 << "SSL_SESSION_to_bytes did not round-trip";
839
840 // Verify the SSL_SESSION also decodes with the legacy API.
841 const uint8_t *cptr = input.data();
842 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
843 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
844 EXPECT_EQ(cptr, input.data() + input.size());
845
846 // Verify the SSL_SESSION encoding round-trips via the legacy API.
847 int len = i2d_SSL_SESSION(session.get(), NULL);
848 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
849 ASSERT_EQ(static_cast<size_t>(len), input.size())
850 << "i2d_SSL_SESSION(NULL) returned invalid length";
851
852 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
853 ASSERT_TRUE(encoded);
854
855 uint8_t *ptr = encoded.get();
856 len = i2d_SSL_SESSION(session.get(), &ptr);
857 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
858 ASSERT_EQ(static_cast<size_t>(len), input.size())
859 << "i2d_SSL_SESSION(NULL) returned invalid length";
860 ASSERT_EQ(ptr, encoded.get() + input.size())
861 << "i2d_SSL_SESSION did not advance ptr correctly";
862 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
863 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400864 }
865
David Benjamina486c6c2019-03-28 18:32:38 -0500866 for (const char *input_b64 : {
867 kBadSessionExtraField,
868 kBadSessionVersion,
869 kBadSessionTrailingData,
870 }) {
871 SCOPED_TRACE(std::string(input_b64));
872 std::vector<uint8_t> input;
873 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400874
David Benjamina486c6c2019-03-28 18:32:38 -0500875 // Verify that the SSL_SESSION fails to decode.
876 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
877 ASSERT_TRUE(ssl_ctx);
878 bssl::UniquePtr<SSL_SESSION> session(
879 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
880 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
881 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400882 }
David Benjaminf297e022015-05-28 19:55:29 -0400883}
884
David Benjamin321fcdc2017-04-24 11:42:42 -0400885static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
886 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700887 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400888 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700889 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
890 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400891}
892
893TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800894 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400895 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
896 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
897 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700898 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
899 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
900 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500901}
902
David Benjamin348f0d82017-08-10 16:06:27 -0400903TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400904 static const struct {
905 int id;
906 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400907 int cipher_nid;
908 int digest_nid;
909 int kx_nid;
910 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400911 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400912 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400913 {
914 SSL3_CK_RSA_DES_192_CBC3_SHA,
915 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
916 NID_des_ede3_cbc,
917 NID_sha1,
918 NID_kx_rsa,
919 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400920 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400921 },
922 {
923 TLS1_CK_RSA_WITH_AES_128_SHA,
924 "TLS_RSA_WITH_AES_128_CBC_SHA",
925 NID_aes_128_cbc,
926 NID_sha1,
927 NID_kx_rsa,
928 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400929 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400930 },
931 {
932 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
933 "TLS_PSK_WITH_AES_256_CBC_SHA",
934 NID_aes_256_cbc,
935 NID_sha1,
936 NID_kx_psk,
937 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400938 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400939 },
940 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400941 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
942 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400943 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400944 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400945 NID_kx_ecdhe,
946 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400947 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400948 },
949 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400950 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
951 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400952 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400953 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400954 NID_kx_ecdhe,
955 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400956 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400957 },
958 {
959 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
960 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
961 NID_aes_128_gcm,
962 NID_undef,
963 NID_kx_ecdhe,
964 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400965 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400966 },
967 {
968 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
969 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
970 NID_aes_128_gcm,
971 NID_undef,
972 NID_kx_ecdhe,
973 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400974 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400975 },
976 {
977 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
978 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
979 NID_aes_256_gcm,
980 NID_undef,
981 NID_kx_ecdhe,
982 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400983 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400984 },
985 {
986 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
987 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
988 NID_aes_128_cbc,
989 NID_sha1,
990 NID_kx_ecdhe,
991 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400992 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400993 },
994 {
995 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
996 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
997 NID_chacha20_poly1305,
998 NID_undef,
999 NID_kx_ecdhe,
1000 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001001 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001002 },
1003 {
1004 TLS1_CK_AES_256_GCM_SHA384,
1005 "TLS_AES_256_GCM_SHA384",
1006 NID_aes_256_gcm,
1007 NID_undef,
1008 NID_kx_any,
1009 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001010 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001011 },
1012 {
1013 TLS1_CK_AES_128_GCM_SHA256,
1014 "TLS_AES_128_GCM_SHA256",
1015 NID_aes_128_gcm,
1016 NID_undef,
1017 NID_kx_any,
1018 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001019 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001020 },
1021 {
1022 TLS1_CK_CHACHA20_POLY1305_SHA256,
1023 "TLS_CHACHA20_POLY1305_SHA256",
1024 NID_chacha20_poly1305,
1025 NID_undef,
1026 NID_kx_any,
1027 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001028 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001029 },
David Benjamin6fff3862017-06-21 21:07:04 -04001030 };
David Benjamin65226252015-02-05 16:49:47 -05001031
David Benjamin6fff3862017-06-21 21:07:04 -04001032 for (const auto &t : kTests) {
1033 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001034
1035 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1036 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001037 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1038
David Benjamine11726a2017-04-23 12:14:28 -04001039 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1040 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001041 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001042
1043 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1044 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1045 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1046 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001047 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001048 }
David Benjamin65226252015-02-05 16:49:47 -05001049}
1050
Steven Valdeza833c352016-11-01 13:39:36 -04001051// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1052// version and ticket length or nullptr on failure.
1053static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1054 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001055 std::vector<uint8_t> der;
1056 if (!DecodeBase64(&der, kOpenSSLSession)) {
1057 return nullptr;
1058 }
Adam Langley46db7af2017-02-01 15:49:37 -08001059
1060 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1061 if (!ssl_ctx) {
1062 return nullptr;
1063 }
David Benjaminaaef8332018-06-29 16:45:49 -04001064 // Use a garbage ticket.
1065 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001066 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001067 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001068 if (!session ||
1069 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1070 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001071 return nullptr;
1072 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001073 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001074#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001075 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001076#else
David Benjaminaaef8332018-06-29 16:45:49 -04001077 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001078#endif
David Benjamin422fe082015-07-21 22:03:43 -04001079 return session;
1080}
1081
David Benjaminafc64de2016-07-19 17:12:41 +02001082static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001083 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001084 if (!bio) {
1085 return false;
1086 }
1087 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001088 BIO_up_ref(bio.get());
1089 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001090 int ret = SSL_connect(ssl);
1091 if (ret > 0) {
1092 // SSL_connect should fail without a BIO to write to.
1093 return false;
1094 }
1095 ERR_clear_error();
1096
1097 const uint8_t *client_hello;
1098 size_t client_hello_len;
1099 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1100 return false;
1101 }
1102 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1103 return true;
1104}
1105
Steven Valdeza833c352016-11-01 13:39:36 -04001106// GetClientHelloLen creates a client SSL connection with the specified version
1107// and ticket length. It returns the length of the ClientHello, not including
1108// the record header, on success and zero on error.
1109static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1110 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001111 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001112 bssl::UniquePtr<SSL_SESSION> session =
1113 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001114 if (!ctx || !session) {
1115 return 0;
1116 }
Steven Valdeza833c352016-11-01 13:39:36 -04001117
1118 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001119 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001120 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001121 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001122 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001123 return 0;
1124 }
Steven Valdeza833c352016-11-01 13:39:36 -04001125
David Benjaminafc64de2016-07-19 17:12:41 +02001126 std::vector<uint8_t> client_hello;
1127 if (!GetClientHello(ssl.get(), &client_hello) ||
1128 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001129 return 0;
1130 }
Steven Valdeza833c352016-11-01 13:39:36 -04001131
David Benjaminafc64de2016-07-19 17:12:41 +02001132 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001133}
1134
David Benjamina486c6c2019-03-28 18:32:38 -05001135TEST(SSLTest, Padding) {
1136 struct PaddingVersions {
1137 uint16_t max_version, session_version;
1138 };
1139 static const PaddingVersions kPaddingVersions[] = {
1140 // Test the padding extension at TLS 1.2.
1141 {TLS1_2_VERSION, TLS1_2_VERSION},
1142 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1143 // will be no PSK binder after the padding extension.
1144 {TLS1_3_VERSION, TLS1_2_VERSION},
1145 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1146 // will be a PSK binder after the padding extension.
1147 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001148
David Benjamina486c6c2019-03-28 18:32:38 -05001149 };
David Benjamin422fe082015-07-21 22:03:43 -04001150
David Benjamina486c6c2019-03-28 18:32:38 -05001151 struct PaddingTest {
1152 size_t input_len, padded_len;
1153 };
1154 static const PaddingTest kPaddingTests[] = {
1155 // ClientHellos of length below 0x100 do not require padding.
1156 {0xfe, 0xfe},
1157 {0xff, 0xff},
1158 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1159 {0x100, 0x200},
1160 {0x123, 0x200},
1161 {0x1fb, 0x200},
1162 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1163 // padding extension takes a minimum of four bytes plus one required
1164 // content
1165 // byte. (To work around yet more server bugs, we avoid empty final
1166 // extensions.)
1167 {0x1fc, 0x201},
1168 {0x1fd, 0x202},
1169 {0x1fe, 0x203},
1170 {0x1ff, 0x204},
1171 // Finally, larger ClientHellos need no padding.
1172 {0x200, 0x200},
1173 {0x201, 0x201},
1174 };
David Benjamin422fe082015-07-21 22:03:43 -04001175
David Benjamina486c6c2019-03-28 18:32:38 -05001176 for (const PaddingVersions &versions : kPaddingVersions) {
1177 SCOPED_TRACE(versions.max_version);
1178 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001179
David Benjamina486c6c2019-03-28 18:32:38 -05001180 // Sample a baseline length.
1181 size_t base_len =
1182 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1183 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1184
1185 for (const PaddingTest &test : kPaddingTests) {
1186 SCOPED_TRACE(test.input_len);
1187 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1188
1189 size_t padded_len =
1190 GetClientHelloLen(versions.max_version, versions.session_version,
1191 1 + test.input_len - base_len);
1192 EXPECT_EQ(padded_len, test.padded_len)
1193 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001194 }
1195 }
David Benjamin422fe082015-07-21 22:03:43 -04001196}
1197
David Benjamin2f3958a2021-04-16 11:55:23 -04001198static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1199 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1200 if (!bio) {
1201 return nullptr;
1202 }
1203 return bssl::UniquePtr<X509>(
1204 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1205}
1206
1207static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1208 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1209 if (!bio) {
1210 return nullptr;
1211 }
1212 return bssl::UniquePtr<EVP_PKEY>(
1213 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1214}
1215
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001216static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001217 static const char kCertPEM[] =
1218 "-----BEGIN CERTIFICATE-----\n"
1219 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1220 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1221 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1222 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1223 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1224 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1225 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1226 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1227 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1228 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1229 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1230 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1231 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1232 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001233 return CertFromPEM(kCertPEM);
David Benjaminde942382016-02-11 12:02:01 -05001234}
1235
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001236static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001237 static const char kKeyPEM[] =
1238 "-----BEGIN RSA PRIVATE KEY-----\n"
1239 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1240 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1241 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1242 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1243 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1244 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1245 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1246 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1247 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1248 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1249 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1250 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1251 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1252 "-----END RSA PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001253 return KeyFromPEM(kKeyPEM);
David Benjaminde942382016-02-11 12:02:01 -05001254}
1255
David Benjamin9b2cdb72021-04-01 23:21:53 -04001256static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1257 const SSL_METHOD *method) {
1258 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1259 bssl::UniquePtr<X509> cert = GetTestCertificate();
1260 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1261 if (!ctx || !cert || !key ||
1262 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1263 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1264 return nullptr;
1265 }
1266 return ctx;
1267}
1268
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001269static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001270 static const char kCertPEM[] =
1271 "-----BEGIN CERTIFICATE-----\n"
1272 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1273 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1274 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1275 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1276 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1277 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1278 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1279 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1280 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1281 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1282 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001283 return CertFromPEM(kCertPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001284}
1285
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001286static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001287 static const char kKeyPEM[] =
1288 "-----BEGIN PRIVATE KEY-----\n"
1289 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1290 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1291 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1292 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001293 return KeyFromPEM(kKeyPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001294}
1295
Adam Langleyd04ca952017-02-28 11:26:51 -08001296static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1297 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1298 char *name, *header;
1299 uint8_t *data;
1300 long data_len;
1301 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1302 &data_len)) {
1303 return nullptr;
1304 }
1305 OPENSSL_free(name);
1306 OPENSSL_free(header);
1307
1308 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1309 CRYPTO_BUFFER_new(data, data_len, nullptr));
1310 OPENSSL_free(data);
1311 return ret;
1312}
1313
1314static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001315 static const char kCertPEM[] =
1316 "-----BEGIN CERTIFICATE-----\n"
1317 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1318 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1319 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1320 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1321 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1322 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1323 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1324 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1325 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1326 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1327 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1328 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1329 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1330 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1331 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1332 "1ngWZ7Ih\n"
1333 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001334 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001335}
1336
Adam Langleyd04ca952017-02-28 11:26:51 -08001337static bssl::UniquePtr<X509> X509FromBuffer(
1338 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1339 if (!buffer) {
1340 return nullptr;
1341 }
1342 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1343 return bssl::UniquePtr<X509>(
1344 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1345}
1346
1347static bssl::UniquePtr<X509> GetChainTestCertificate() {
1348 return X509FromBuffer(GetChainTestCertificateBuffer());
1349}
1350
1351static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001352 static const char kCertPEM[] =
1353 "-----BEGIN CERTIFICATE-----\n"
1354 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1355 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1356 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1357 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1358 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1359 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1360 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1361 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1362 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1363 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1364 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1365 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1366 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1367 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1368 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1369 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001370 return BufferFromPEM(kCertPEM);
1371}
1372
1373static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1374 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001375}
1376
1377static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1378 static const char kKeyPEM[] =
1379 "-----BEGIN PRIVATE KEY-----\n"
1380 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1381 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1382 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1383 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1384 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1385 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1386 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1387 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1388 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1389 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1390 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1391 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1392 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1393 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1394 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1395 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1396 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1397 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1398 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1399 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1400 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1401 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1402 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1403 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1404 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1405 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1406 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001407 return KeyFromPEM(kKeyPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001408}
1409
David Benjamin83a49932021-05-20 15:57:09 -04001410static bool CompleteHandshakes(SSL *client, SSL *server) {
1411 // Drive both their handshakes to completion.
1412 for (;;) {
1413 int client_ret = SSL_do_handshake(client);
1414 int client_err = SSL_get_error(client, client_ret);
1415 if (client_err != SSL_ERROR_NONE &&
1416 client_err != SSL_ERROR_WANT_READ &&
1417 client_err != SSL_ERROR_WANT_WRITE &&
1418 client_err != SSL_ERROR_PENDING_TICKET) {
1419 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
1420 return false;
1421 }
1422
1423 int server_ret = SSL_do_handshake(server);
1424 int server_err = SSL_get_error(server, server_ret);
1425 if (server_err != SSL_ERROR_NONE &&
1426 server_err != SSL_ERROR_WANT_READ &&
1427 server_err != SSL_ERROR_WANT_WRITE &&
1428 server_err != SSL_ERROR_PENDING_TICKET) {
1429 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
1430 return false;
1431 }
1432
1433 if (client_ret == 1 && server_ret == 1) {
1434 break;
1435 }
1436 }
1437
1438 return true;
1439}
1440
1441static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1442 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1443 // not pick them up until |SSL_read|.
1444 for (;;) {
1445 int server_ret = SSL_write(server, nullptr, 0);
1446 int server_err = SSL_get_error(server, server_ret);
1447 // The server may either succeed (|server_ret| is zero) or block on write
1448 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1449 if (server_ret > 0 ||
1450 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1451 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1452 server_err);
1453 return false;
1454 }
1455
1456 int client_ret = SSL_read(client, nullptr, 0);
1457 int client_err = SSL_get_error(client, client_ret);
1458 // The client must always block on read.
1459 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1460 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1461 client_err);
1462 return false;
1463 }
1464
1465 // The server flushed everything it had to write.
1466 if (server_ret == 0) {
1467 return true;
1468 }
1469 }
1470}
1471
1472// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1473// are paired with each other. It does not run the handshake. The caller is
1474// expected to configure the objects and drive the handshake as needed.
1475static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1476 bssl::UniquePtr<SSL> *out_server,
1477 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1478 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1479 if (!client || !server) {
1480 return false;
1481 }
1482 SSL_set_connect_state(client.get());
1483 SSL_set_accept_state(server.get());
1484
1485 BIO *bio1, *bio2;
1486 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1487 return false;
1488 }
1489 // SSL_set_bio takes ownership.
1490 SSL_set_bio(client.get(), bio1, bio1);
1491 SSL_set_bio(server.get(), bio2, bio2);
1492
1493 *out_client = std::move(client);
1494 *out_server = std::move(server);
1495 return true;
1496}
1497
1498struct ClientConfig {
1499 SSL_SESSION *session = nullptr;
1500 std::string servername;
1501 bool early_data = false;
1502};
1503
1504static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1505 bssl::UniquePtr<SSL> *out_server,
1506 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1507 const ClientConfig &config = ClientConfig(),
1508 bool shed_handshake_config = true) {
1509 bssl::UniquePtr<SSL> client, server;
1510 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
1511 return false;
1512 }
1513 if (config.early_data) {
1514 SSL_set_early_data_enabled(client.get(), 1);
1515 }
1516 if (config.session) {
1517 SSL_set_session(client.get(), config.session);
1518 }
1519 if (!config.servername.empty() &&
1520 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1521 return false;
1522 }
1523
1524 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1525 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1526
1527 if (!CompleteHandshakes(client.get(), server.get())) {
1528 return false;
1529 }
1530
1531 *out_client = std::move(client);
1532 *out_server = std::move(server);
1533 return true;
1534}
1535
David Benjamin9734e442021-06-15 13:58:12 -04001536static bssl::UniquePtr<SSL_SESSION> g_last_session;
1537
1538static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1539 // Save the most recent session.
1540 g_last_session.reset(session);
1541 return 1;
1542}
1543
1544static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
1545 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1546 const ClientConfig &config = ClientConfig()) {
1547 g_last_session = nullptr;
1548 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1549
1550 // Connect client and server to get a session.
1551 bssl::UniquePtr<SSL> client, server;
1552 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1553 config) ||
1554 !FlushNewSessionTickets(client.get(), server.get())) {
1555 fprintf(stderr, "Failed to connect client and server.\n");
1556 return nullptr;
1557 }
1558
1559 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1560
1561 if (!g_last_session) {
1562 fprintf(stderr, "Client did not receive a session.\n");
1563 return nullptr;
1564 }
1565 return std::move(g_last_session);
1566}
1567
David Benjaminc79ae7a2017-08-29 16:09:44 -04001568// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1569// before configuring as a server.
1570TEST(SSLTest, ClientCAList) {
1571 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1572 ASSERT_TRUE(ctx);
1573 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1574 ASSERT_TRUE(ssl);
1575
1576 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1577 ASSERT_TRUE(name);
1578
1579 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1580 ASSERT_TRUE(name_dup);
1581
1582 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1583 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001584 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001585
1586 // |SSL_set_client_CA_list| takes ownership.
1587 SSL_set_client_CA_list(ssl.get(), stack.release());
1588
1589 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1590 ASSERT_TRUE(result);
1591 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1592 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1593}
1594
1595TEST(SSLTest, AddClientCA) {
1596 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1597 ASSERT_TRUE(ctx);
1598 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1599 ASSERT_TRUE(ssl);
1600
1601 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1602 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1603 ASSERT_TRUE(cert1 && cert2);
1604 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1605 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1606
1607 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1608
1609 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1610 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1611
1612 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1613 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1614 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1615 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1616
1617 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1618
1619 list = SSL_get_client_CA_list(ssl.get());
1620 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1621 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1622 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1623 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1624}
1625
David Benjamin24545c52021-06-07 16:05:07 -04001626struct ECHConfigParams {
1627 uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1628 uint16_t config_id = 1;
1629 std::string public_name = "example.com";
1630 const EVP_HPKE_KEY *key = nullptr;
1631 // kem_id, if zero, takes its value from |key|.
1632 uint16_t kem_id = 0;
1633 // public_key, if empty takes its value from |key|.
1634 std::vector<uint8_t> public_key;
1635 size_t max_name_len = 16;
1636 // cipher_suites is a list of code points which should contain pairs of KDF
1637 // and AEAD IDs.
1638 std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1639 EVP_HPKE_AES_128_GCM};
1640 std::vector<uint8_t> extensions;
1641};
Daniel McArdle00e434d2021-02-18 11:47:18 -05001642
David Benjamin24545c52021-06-07 16:05:07 -04001643// MakeECHConfig serializes an ECHConfig from |params| and writes it to
1644// |*out|.
1645bool MakeECHConfig(std::vector<uint8_t> *out,
1646 const ECHConfigParams &params) {
1647 uint16_t kem_id = params.kem_id == 0
1648 ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1649 : params.kem_id;
1650 std::vector<uint8_t> public_key = params.public_key;
1651 if (public_key.empty()) {
1652 public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1653 size_t len;
1654 if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1655 public_key.size())) {
1656 return false;
1657 }
1658 public_key.resize(len);
1659 }
Daniel McArdle00e434d2021-02-18 11:47:18 -05001660
Daniel McArdle00e434d2021-02-18 11:47:18 -05001661 bssl::ScopedCBB cbb;
1662 CBB contents, child;
Daniel McArdle00e434d2021-02-18 11:47:18 -05001663 if (!CBB_init(cbb.get(), 64) ||
David Benjamin24545c52021-06-07 16:05:07 -04001664 !CBB_add_u16(cbb.get(), params.version) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001665 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
David Benjamin24545c52021-06-07 16:05:07 -04001666 !CBB_add_u8(&contents, params.config_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001667 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001668 !CBB_add_u16_length_prefixed(&contents, &child) ||
1669 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001670 !CBB_add_u16_length_prefixed(&contents, &child)) {
1671 return false;
1672 }
David Benjamin24545c52021-06-07 16:05:07 -04001673 for (uint16_t cipher_suite : params.cipher_suites) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001674 if (!CBB_add_u16(&child, cipher_suite)) {
1675 return false;
1676 }
1677 }
David Benjamin24545c52021-06-07 16:05:07 -04001678 if (!CBB_add_u16(&contents, params.max_name_len) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001679 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001680 !CBB_add_bytes(
1681 &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1682 params.public_name.size()) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001683 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001684 !CBB_add_bytes(&child, params.extensions.data(),
1685 params.extensions.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001686 !CBB_flush(cbb.get())) {
1687 return false;
1688 }
1689
1690 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1691 return true;
1692}
1693
David Benjamin83a49932021-05-20 15:57:09 -04001694static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys() {
1695 bssl::ScopedEVP_HPKE_KEY key;
1696 uint8_t *ech_config;
1697 size_t ech_config_len;
1698 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1699 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
1700 /*config_id=*/1, key.get(), "public.example",
1701 16)) {
1702 return nullptr;
1703 }
1704 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1705
1706 // Install a non-retry config.
1707 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1708 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1709 ech_config_len, key.get())) {
1710 return nullptr;
1711 }
1712 return keys;
1713}
1714
1715static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1716 uint8_t *ech_config_list;
1717 size_t ech_config_list_len;
1718 if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1719 &ech_config_list_len)) {
1720 return false;
1721 }
1722 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1723 return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1724}
1725
David Benjamin24545c52021-06-07 16:05:07 -04001726// Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1727// output values as expected.
1728TEST(SSLTest, MarshalECHConfig) {
1729 static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1730 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1731 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1732 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1733 bssl::ScopedEVP_HPKE_KEY key;
1734 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1735 kPrivateKey, sizeof(kPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001736
David Benjamin24545c52021-06-07 16:05:07 -04001737 static const uint8_t kECHConfig[] = {
1738 // version
1739 0xfe, 0x0a,
1740 // length
1741 0x00, 0x43,
1742 // contents.config_id
1743 0x01,
1744 // contents.kem_id
1745 0x00, 0x20,
1746 // contents.public_key
1747 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1748 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1749 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1750 // contents.cipher_suites
1751 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1752 // contents.maximum_name_length
1753 0x00, 0x10,
1754 // contents.public_name
1755 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1756 0x6d, 0x70, 0x6c, 0x65,
1757 // contents.extensions
1758 0x00, 0x00};
1759 uint8_t *ech_config;
1760 size_t ech_config_len;
1761 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1762 /*config_id=*/1, key.get(),
1763 "public.example", 16));
1764 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1765 EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1766
1767 // Generate a second ECHConfig.
1768 bssl::ScopedEVP_HPKE_KEY key2;
1769 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1770 uint8_t *ech_config2;
1771 size_t ech_config2_len;
1772 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1773 /*config_id=*/2, key2.get(),
1774 "public.example", 16));
1775 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1776
1777 // Install both ECHConfigs in an |SSL_ECH_KEYS|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001778 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1779 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001780 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1781 ech_config_len, key.get()));
1782 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1783 ech_config2_len, key2.get()));
1784
1785 // The ECHConfigList should be correctly serialized.
1786 uint8_t *ech_config_list;
1787 size_t ech_config_list_len;
1788 ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1789 &ech_config_list_len));
1790 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1791
1792 // ECHConfigList is just the concatenation with a length prefix.
1793 size_t len = ech_config_len + ech_config2_len;
1794 std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1795 expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1796 expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1797 EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
David Benjamin24545c52021-06-07 16:05:07 -04001798}
1799
1800TEST(SSLTest, ECHHasDuplicateConfigID) {
1801 const struct {
1802 std::vector<uint8_t> ids;
1803 bool has_duplicate;
1804 } kTests[] = {
1805 {{}, false},
1806 {{1}, false},
1807 {{1, 2, 3, 255}, false},
1808 {{1, 2, 3, 1}, true},
1809 };
1810 for (const auto &test : kTests) {
1811 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1812 ASSERT_TRUE(keys);
1813 for (const uint8_t id : test.ids) {
1814 bssl::ScopedEVP_HPKE_KEY key;
1815 ASSERT_TRUE(
1816 EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1817 uint8_t *ech_config;
1818 size_t ech_config_len;
1819 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
1820 key.get(), "public.example", 16));
1821 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1822 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1823 ech_config, ech_config_len, key.get()));
1824 }
1825
1826 EXPECT_EQ(test.has_duplicate ? 1 : 0,
1827 SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
1828 }
1829}
1830
1831// Test that |SSL_ECH_KEYS_add| checks consistency between the public and
1832// private key.
1833TEST(SSLTest, ECHKeyConsistency) {
1834 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1835 ASSERT_TRUE(keys);
1836 bssl::ScopedEVP_HPKE_KEY key;
1837 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1838 uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
1839 size_t public_key_len;
1840 ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
1841 sizeof(public_key)));
1842
1843 // Adding an ECHConfig with the matching public key succeeds.
1844 ECHConfigParams params;
1845 params.key = key.get();
1846 std::vector<uint8_t> ech_config;
1847 ASSERT_TRUE(MakeECHConfig(&ech_config, params));
1848 EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1849 ech_config.data(), ech_config.size(),
1850 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001851
David Benjaminc890ae52021-06-06 13:32:29 -04001852 // Adding an ECHConfig with the wrong public key is an error.
1853 bssl::ScopedEVP_HPKE_KEY wrong_key;
1854 ASSERT_TRUE(
1855 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjamin24545c52021-06-07 16:05:07 -04001856 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1857 ech_config.data(), ech_config.size(),
1858 wrong_key.get()));
1859
1860 // Adding an ECHConfig with a truncated public key is an error.
1861 ECHConfigParams truncated;
1862 truncated.key = key.get();
1863 truncated.public_key.assign(public_key, public_key + public_key_len - 1);
1864 ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
1865 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1866 ech_config.data(), ech_config.size(), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001867
David Benjaminc890ae52021-06-06 13:32:29 -04001868 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
1869 // error.
David Benjamin24545c52021-06-07 16:05:07 -04001870 ECHConfigParams wrong_kem;
1871 wrong_kem.key = key.get();
1872 wrong_kem.kem_id = 0x0010; // DHKEM(P-256, HKDF-SHA256)
1873 ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
David Benjaminc890ae52021-06-06 13:32:29 -04001874 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1875 ech_config.data(), ech_config.size(),
1876 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001877}
1878
David Benjaminc3b373b2021-06-06 13:04:26 -04001879// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001880// has no retry configs.
1881TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
David Benjamin24545c52021-06-07 16:05:07 -04001882 bssl::ScopedEVP_HPKE_KEY key;
1883 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1884 uint8_t *ech_config;
1885 size_t ech_config_len;
1886 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1887 /*config_id=*/1, key.get(),
1888 "public.example", 16));
1889 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001890
David Benjamin24545c52021-06-07 16:05:07 -04001891 // Install a non-retry config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001892 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1893 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001894 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
1895 ech_config_len, key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001896
David Benjamin24545c52021-06-07 16:05:07 -04001897 // |keys| has no retry configs.
1898 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1899 ASSERT_TRUE(ctx);
1900 EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001901
1902 // Add the same ECHConfig to the list, but this time mark it as a retry
1903 // config.
David Benjamin24545c52021-06-07 16:05:07 -04001904 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1905 ech_config_len, key.get()));
1906 EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001907}
1908
1909// Test that the server APIs reject ECHConfigs with unsupported features.
1910TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001911 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1912 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04001913 bssl::ScopedEVP_HPKE_KEY key;
David Benjamin24545c52021-06-07 16:05:07 -04001914 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001915
1916 // Unsupported versions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001917 ECHConfigParams unsupported_version;
1918 unsupported_version.version = 0xffff;
1919 unsupported_version.key = key.get();
Daniel McArdle00e434d2021-02-18 11:47:18 -05001920 std::vector<uint8_t> ech_config;
David Benjamin24545c52021-06-07 16:05:07 -04001921 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
David Benjaminc3b373b2021-06-06 13:04:26 -04001922 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1923 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001924 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001925
David Benjamin24545c52021-06-07 16:05:07 -04001926 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1927 ECHConfigParams unsupported_kdf;
1928 unsupported_kdf.key = key.get();
1929 unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
1930 EVP_HPKE_AES_128_GCM};
1931 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
1932 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1933 ech_config.data(), ech_config.size(),
1934 key.get()));
1935 ECHConfigParams unsupported_aead;
1936 unsupported_aead.key = key.get();
1937 unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
1938 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
1939 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1940 ech_config.data(), ech_config.size(),
1941 key.get()));
1942
1943
Daniel McArdle00e434d2021-02-18 11:47:18 -05001944 // Unsupported extensions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001945 ECHConfigParams extensions;
1946 extensions.key = key.get();
1947 extensions.extensions = {0x00, 0x01, 0x00, 0x00};
1948 ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001949 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1950 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001951 key.get()));
David Benjamin9cbe7372021-06-15 18:09:10 -04001952
1953 // Invalid public names are rejected.
1954 ECHConfigParams invalid_public_name;
1955 invalid_public_name.key = key.get();
1956 invalid_public_name.public_name = "dns_names_have_no_underscores.example";
1957 ASSERT_TRUE(MakeECHConfig(&ech_config, invalid_public_name));
1958 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1959 ech_config.data(), ech_config.size(),
1960 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001961}
1962
David Benjamin83a49932021-05-20 15:57:09 -04001963// Test that |SSL_get_client_random| reports the correct value on both client
1964// and server in ECH. The client sends two different random values. When ECH is
1965// accepted, we should report the inner one.
1966TEST(SSLTest, ECHClientRandomsMatch) {
1967 bssl::UniquePtr<SSL_CTX> server_ctx =
1968 CreateContextWithTestCertificate(TLS_method());
1969 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
1970 ASSERT_TRUE(keys);
1971 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
1972
1973 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1974 ASSERT_TRUE(client_ctx);
1975 bssl::UniquePtr<SSL> client, server;
1976 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
1977 server_ctx.get()));
1978 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
1979 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
1980
1981 EXPECT_TRUE(SSL_ech_accepted(client.get()));
1982 EXPECT_TRUE(SSL_ech_accepted(server.get()));
1983
1984 // An ECH server will fairly naturally record the inner ClientHello random,
1985 // but an ECH client may forget to update the random once ClientHelloInner is
1986 // selected.
1987 uint8_t client_random1[SSL3_RANDOM_SIZE];
1988 uint8_t client_random2[SSL3_RANDOM_SIZE];
1989 ASSERT_EQ(sizeof(client_random1),
1990 SSL_get_client_random(client.get(), client_random1,
1991 sizeof(client_random1)));
1992 ASSERT_EQ(sizeof(client_random2),
1993 SSL_get_client_random(server.get(), client_random2,
1994 sizeof(client_random2)));
1995 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
1996}
1997
1998// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
1999// of the ClientHello and ECH extension, respectively, when a client created
2000// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
2001// maximum name length |max_name_len|.
2002static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
2003 size_t *out_ech_len, size_t max_name_len,
2004 const char *name) {
2005 bssl::ScopedEVP_HPKE_KEY key;
2006 uint8_t *ech_config;
2007 size_t ech_config_len;
2008 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
2009 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
2010 /*config_id=*/1, key.get(), "public.example",
2011 max_name_len)) {
2012 return false;
2013 }
2014 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2015
2016 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2017 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2018 ech_config_len, key.get())) {
2019 return false;
2020 }
2021
2022 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
2023 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
2024 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
2025 return false;
2026 }
2027 SSL_set_connect_state(ssl.get());
2028
2029 std::vector<uint8_t> client_hello;
2030 SSL_CLIENT_HELLO parsed;
2031 const uint8_t *unused;
2032 if (!GetClientHello(ssl.get(), &client_hello) ||
2033 !ssl_client_hello_init(
2034 ssl.get(), &parsed,
2035 // Skip record and handshake headers. This assumes the ClientHello
2036 // fits in one record.
2037 MakeConstSpan(client_hello)
2038 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
2039 !SSL_early_callback_ctx_extension_get(
2040 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2041 return false;
2042 }
2043 *out_client_hello_len = client_hello.size();
2044 return true;
2045}
2046
2047TEST(SSLTest, ECHPadding) {
2048 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2049 ASSERT_TRUE(ctx);
2050
2051 // Sample lengths with max_name_len = 128 as baseline.
2052 size_t client_hello_len_baseline, ech_len_baseline;
2053 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2054 &ech_len_baseline, 128, "example.com"));
2055
2056 // Check that all name lengths under the server's maximum look the same.
2057 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2058 SCOPED_TRACE(name_len);
2059 size_t client_hello_len, ech_len;
2060 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2061 std::string(name_len, 'a').c_str()));
2062 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2063 EXPECT_EQ(ech_len, ech_len_baseline);
2064 }
2065
2066 // When sending no SNI, we must still pad as if we are sending one.
2067 size_t client_hello_len, ech_len;
2068 ASSERT_TRUE(
2069 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2070 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2071 EXPECT_EQ(ech_len, ech_len_baseline);
2072
2073 size_t client_hello_len_129, ech_len_129;
2074 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_129, &ech_len_129, 128,
2075 std::string(129, 'a').c_str()));
2076 // The padding calculation should not pad beyond the maximum.
2077 EXPECT_GT(ech_len_129, ech_len_baseline);
2078
2079 // If the SNI exceeds the maximum name length, we apply some generic padding,
2080 // so close name lengths still match.
2081 for (size_t name_len : {129, 130, 131, 132}) {
2082 SCOPED_TRACE(name_len);
2083 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2084 std::string(name_len, 'a').c_str()));
2085 EXPECT_EQ(client_hello_len, client_hello_len_129);
2086 EXPECT_EQ(ech_len, ech_len_129);
2087 }
2088}
2089
David Benjamin9cbe7372021-06-15 18:09:10 -04002090TEST(SSLTest, ECHPublicName) {
2091 auto str_to_span = [](const char *str) -> Span<const uint8_t> {
2092 return MakeConstSpan(reinterpret_cast<const uint8_t *>(str), strlen(str));
2093 };
2094
2095 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("")));
2096 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("example.com")));
2097 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(".example.com")));
2098 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.com.")));
2099 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example..com")));
2100 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.-example.com")));
2101 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.example-.com")));
2102 EXPECT_FALSE(
2103 ssl_is_valid_ech_public_name(str_to_span("no_underscores.example")));
2104 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2105 str_to_span("invalid_chars.\x01.example")));
2106 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2107 str_to_span("invalid_chars.\xff.example")));
2108 static const uint8_t kWithNUL[] = {'t', 'e', 's', 't', 0};
2109 EXPECT_FALSE(ssl_is_valid_ech_public_name(kWithNUL));
2110
2111 // Test an LDH label with every character and the maximum length.
2112 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span(
2113 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789")));
2114 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(
2115 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-01234567899")));
2116
2117 // Inputs that parse as IPv4 addresses are rejected.
2118 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.0.0.1")));
2119 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0177.0.0.01")));
2120 EXPECT_FALSE(
2121 ssl_is_valid_ech_public_name(str_to_span("0x7f.0x.0x.0x00000001")));
2122 EXPECT_FALSE(
2123 ssl_is_valid_ech_public_name(str_to_span("0XAB.0XCD.0XEF.0X01")));
2124 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0.0.0.0")));
2125 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("255.255.255.255")));
2126 // Out-of-bounds or overflowing components are not IP addresses.
2127 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("256.255.255.255")));
2128 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("255.0x100.255.255")));
2129 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("255.255.255.0400")));
2130 EXPECT_TRUE(ssl_is_valid_ech_public_name(
2131 str_to_span("255.255.255.0x100000000")));
2132 // Invalid characters for the base are not IP addresses.
2133 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("12a.0.0.1")));
2134 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("0xg.0.0.1")));
2135 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("08.0.0.1")));
2136 // Trailing components can be merged into a single component.
2137 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.0.1")));
2138 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.1")));
2139 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("2130706433")));
2140 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x7f000001")));
2141 // Merged components must respect their limits.
2142 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0.0.0.0xff")));
2143 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0.0.0xffff")));
2144 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0.0xffffff")));
2145 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0xffffffff")));
2146 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("0.0.0.0x100")));
2147 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("0.0.0x10000")));
2148 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("0.0x1000000")));
2149 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("0x100000000")));
2150 // Correctly handle overflow in decimal and octal.
2151 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("037777777777")));
2152 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("040000000000")));
2153 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("4294967295")));
2154 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("4294967296")));
2155}
2156
David Benjamin83a49932021-05-20 15:57:09 -04002157#if defined(OPENSSL_THREADS)
2158// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2159// in use on other threads. This test is intended to be run with TSan.
2160TEST(SSLTest, ECHThreads) {
2161 // Generate a pair of ECHConfigs.
2162 bssl::ScopedEVP_HPKE_KEY key1;
2163 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2164 uint8_t *ech_config1;
2165 size_t ech_config1_len;
2166 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2167 /*config_id=*/1, key1.get(),
2168 "public.example", 16));
2169 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2170 bssl::ScopedEVP_HPKE_KEY key2;
2171 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2172 uint8_t *ech_config2;
2173 size_t ech_config2_len;
2174 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2175 /*config_id=*/2, key2.get(),
2176 "public.example", 16));
2177 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2178
2179 // |keys1| contains the first config. |keys12| contains both.
2180 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2181 ASSERT_TRUE(keys1);
2182 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2183 ech_config1_len, key1.get()));
2184 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2185 ASSERT_TRUE(keys12);
2186 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2187 ech_config2_len, key2.get()));
2188 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2189 ech_config1_len, key1.get()));
2190
2191 bssl::UniquePtr<SSL_CTX> server_ctx =
2192 CreateContextWithTestCertificate(TLS_method());
2193 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2194
2195 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2196 ASSERT_TRUE(client_ctx);
2197 bssl::UniquePtr<SSL> client, server;
2198 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2199 server_ctx.get()));
2200 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2201
2202 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2203 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2204 // the same whichever the server uses.
2205 std::vector<std::thread> threads;
2206 threads.emplace_back([&] {
2207 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2208 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2209 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2210 });
2211 threads.emplace_back([&] {
2212 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2213 });
2214 for (auto &thread : threads) {
2215 thread.join();
2216 }
2217}
2218#endif // OPENSSL_THREADS
2219
David Benjaminc79ae7a2017-08-29 16:09:44 -04002220static void AppendSession(SSL_SESSION *session, void *arg) {
2221 std::vector<SSL_SESSION*> *out =
2222 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2223 out->push_back(session);
2224}
2225
2226// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2227// order.
2228static bool CacheEquals(SSL_CTX *ctx,
2229 const std::vector<SSL_SESSION*> &expected) {
2230 // Check the linked list.
2231 SSL_SESSION *ptr = ctx->session_cache_head;
2232 for (SSL_SESSION *session : expected) {
2233 if (ptr != session) {
2234 return false;
2235 }
2236 // TODO(davidben): This is an absurd way to denote the end of the list.
2237 if (ptr->next ==
2238 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2239 ptr = nullptr;
2240 } else {
2241 ptr = ptr->next;
2242 }
2243 }
2244 if (ptr != nullptr) {
2245 return false;
2246 }
2247
2248 // Check the hash table.
2249 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002250 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002251 expected_copy = expected;
2252
2253 std::sort(actual.begin(), actual.end());
2254 std::sort(expected_copy.begin(), expected_copy.end());
2255
2256 return actual == expected_copy;
2257}
2258
2259static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2260 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2261 if (!ssl_ctx) {
2262 return nullptr;
2263 }
2264 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2265 if (!ret) {
2266 return nullptr;
2267 }
2268
David Benjaminaaef8332018-06-29 16:45:49 -04002269 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2270 OPENSSL_memcpy(id, &number, sizeof(number));
2271 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2272 return nullptr;
2273 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002274 return ret;
2275}
2276
2277// Test that the internal session cache behaves as expected.
2278TEST(SSLTest, InternalSessionCache) {
2279 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2280 ASSERT_TRUE(ctx);
2281
2282 // Prepare 10 test sessions.
2283 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2284 for (int i = 0; i < 10; i++) {
2285 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2286 ASSERT_TRUE(session);
2287 sessions.push_back(std::move(session));
2288 }
2289
2290 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2291
2292 // Insert all the test sessions.
2293 for (const auto &session : sessions) {
2294 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2295 }
2296
2297 // Only the last five should be in the list.
2298 ASSERT_TRUE(CacheEquals(
2299 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2300 sessions[6].get(), sessions[5].get()}));
2301
2302 // Inserting an element already in the cache should fail and leave the cache
2303 // unchanged.
2304 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2305 ASSERT_TRUE(CacheEquals(
2306 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2307 sessions[6].get(), sessions[5].get()}));
2308
2309 // Although collisions should be impossible (256-bit session IDs), the cache
2310 // must handle them gracefully.
2311 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2312 ASSERT_TRUE(collision);
2313 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2314 ASSERT_TRUE(CacheEquals(
2315 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2316 sessions[6].get(), sessions[5].get()}));
2317
2318 // Removing sessions behaves correctly.
2319 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2320 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2321 sessions[8].get(), sessions[5].get()}));
2322
2323 // Removing sessions requires an exact match.
2324 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2325 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2326
2327 // The cache remains unchanged.
2328 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2329 sessions[8].get(), sessions[5].get()}));
2330}
2331
2332static uint16_t EpochFromSequence(uint64_t seq) {
2333 return static_cast<uint16_t>(seq >> 48);
2334}
2335
David Benjamin71dfad42017-07-16 17:27:39 -04002336static const uint8_t kTestName[] = {
2337 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2338 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2339 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2340 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2341 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2342 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2343};
2344
David Benjaminc11ea9422017-08-29 16:33:21 -04002345// SSLVersionTest executes its test cases under all available protocol versions.
2346// Test cases call |Connect| to create a connection using context objects with
2347// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002348class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2349 protected:
2350 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2351
2352 void SetUp() { ResetContexts(); }
2353
2354 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2355 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2356 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2357 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2358 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2359 return nullptr;
2360 }
2361 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002362 }
David Benjamin686bb192016-05-10 15:15:41 -04002363
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002364 void ResetContexts() {
2365 ASSERT_TRUE(cert_);
2366 ASSERT_TRUE(key_);
2367 client_ctx_ = CreateContext();
2368 ASSERT_TRUE(client_ctx_);
2369 server_ctx_ = CreateContext();
2370 ASSERT_TRUE(server_ctx_);
2371 // Set up a server cert. Client certs can be set up explicitly.
2372 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002373 }
David Benjamin686bb192016-05-10 15:15:41 -04002374
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002375 bool UseCertAndKey(SSL_CTX *ctx) const {
2376 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2377 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002378 }
David Benjamin686bb192016-05-10 15:15:41 -04002379
David Benjamina8614602017-09-06 15:40:19 -04002380 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002381 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002382 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002383 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002384 }
2385
2386 uint16_t version() const { return GetParam().version; }
2387
2388 bool is_dtls() const {
2389 return GetParam().ssl_method == VersionParam::is_dtls;
2390 }
2391
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002392 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002393 bssl::UniquePtr<SSL> client_, server_;
2394 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2395 bssl::UniquePtr<X509> cert_;
2396 bssl::UniquePtr<EVP_PKEY> key_;
2397};
2398
David Benjaminbe7006a2019-04-09 18:05:02 -05002399INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2400 testing::ValuesIn(kAllVersions),
2401 [](const testing::TestParamInfo<VersionParam> &i) {
2402 return i.param.name;
2403 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002404
2405TEST_P(SSLVersionTest, SequenceNumber) {
2406 ASSERT_TRUE(Connect());
2407
David Benjamin0fef3052016-11-18 15:11:10 +09002408 // Drain any post-handshake messages to ensure there are no unread records
2409 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002410 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002411
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002412 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2413 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2414 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2415 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002416
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002417 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002418 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002419 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2420 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2421 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2422 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002423
2424 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002425 EXPECT_GT(client_write_seq, server_read_seq);
2426 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002427 } else {
2428 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002429 EXPECT_EQ(client_write_seq, server_read_seq);
2430 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002431 }
2432
2433 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002434 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002435 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2436 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002437
2438 // The client write and server read sequence numbers should have
2439 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002440 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2441 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002442}
2443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002445 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002446 if (is_dtls()) {
2447 return;
David Benjamin686bb192016-05-10 15:15:41 -04002448 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002450
David Benjamin9734e442021-06-15 13:58:12 -04002451 // Shut down half the connection. |SSL_shutdown| will return 0 to signal only
David Benjamin686bb192016-05-10 15:15:41 -04002452 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002453 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002454
2455 // Reading from the server should consume the EOF.
2456 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002457 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2458 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002459
2460 // However, the server may continue to write data and then shut down the
2461 // connection.
2462 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002463 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2464 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2465 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002466
2467 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002468 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2469 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002470}
David Benjamin68f37b72016-11-18 15:14:42 +09002471
David Benjamin9734e442021-06-15 13:58:12 -04002472// Test that, after calling |SSL_shutdown|, |SSL_write| fails.
2473TEST_P(SSLVersionTest, WriteAfterShutdown) {
2474 ASSERT_TRUE(Connect());
2475
2476 for (SSL *ssl : {client_.get(), server_.get()}) {
2477 SCOPED_TRACE(SSL_is_server(ssl) ? "server" : "client");
2478
2479 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2480 ASSERT_TRUE(mem);
2481 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2482
2483 // Shut down half the connection. |SSL_shutdown| will return 0 to signal
2484 // only one side has shut down.
2485 ASSERT_EQ(SSL_shutdown(ssl), 0);
2486
2487 // |ssl| should have written an alert to the transport.
2488 const uint8_t *unused;
2489 size_t len;
2490 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2491 EXPECT_NE(0u, len);
2492 EXPECT_TRUE(BIO_reset(mem.get()));
2493
2494 // Writing should fail.
2495 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2496
2497 // Nothing should be written to the transport.
2498 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2499 EXPECT_EQ(0u, len);
2500 }
2501}
2502
2503// Test that, after sending a fatal alert in a failed |SSL_read|, |SSL_write|
2504// fails.
2505TEST_P(SSLVersionTest, WriteAfterReadSentFatalAlert) {
2506 // Decryption failures are not fatal in DTLS.
2507 if (is_dtls()) {
2508 return;
2509 }
2510
2511 ASSERT_TRUE(Connect());
2512
2513 // Save the write |BIO|s as the test will overwrite them.
2514 bssl::UniquePtr<BIO> client_wbio = bssl::UpRef(SSL_get_wbio(client_.get()));
2515 bssl::UniquePtr<BIO> server_wbio = bssl::UpRef(SSL_get_wbio(server_.get()));
2516
2517 for (bool test_server : {false, true}) {
2518 SCOPED_TRACE(test_server ? "server" : "client");
2519 SSL *ssl = test_server ? server_.get() : client_.get();
2520 BIO *other_wbio = test_server ? client_wbio.get() : server_wbio.get();
2521
2522 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2523 ASSERT_TRUE(mem);
2524 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2525
2526 // Read an invalid record from the peer.
2527 static const uint8_t kInvalidRecord[] = "invalid record";
2528 EXPECT_EQ(int{sizeof(kInvalidRecord)},
2529 BIO_write(other_wbio, kInvalidRecord, sizeof(kInvalidRecord)));
2530 char buf[256];
2531 EXPECT_EQ(-1, SSL_read(ssl, buf, sizeof(buf)));
2532
2533 // |ssl| should have written an alert to the transport.
2534 const uint8_t *unused;
2535 size_t len;
2536 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2537 EXPECT_NE(0u, len);
2538 EXPECT_TRUE(BIO_reset(mem.get()));
2539
2540 // Writing should fail.
2541 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2542
2543 // Nothing should be written to the transport.
2544 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2545 EXPECT_EQ(0u, len);
2546 }
2547}
2548
2549// Test that, after sending a fatal alert from the handshake, |SSL_write| fails.
2550TEST_P(SSLVersionTest, WriteAfterHandshakeSentFatalAlert) {
2551 for (bool test_server : {false, true}) {
2552 SCOPED_TRACE(test_server ? "server" : "client");
2553
2554 bssl::UniquePtr<SSL> ssl(
2555 SSL_new(test_server ? server_ctx_.get() : client_ctx_.get()));
2556 ASSERT_TRUE(ssl);
2557 if (test_server) {
2558 SSL_set_accept_state(ssl.get());
2559 } else {
2560 SSL_set_connect_state(ssl.get());
2561 }
2562
2563 std::vector<uint8_t> invalid;
2564 if (is_dtls()) {
2565 // In DTLS, invalid records are discarded. To cause the handshake to fail,
2566 // use a valid handshake record with invalid contents.
2567 invalid.push_back(SSL3_RT_HANDSHAKE);
2568 invalid.push_back(DTLS1_VERSION >> 8);
2569 invalid.push_back(DTLS1_VERSION & 0xff);
2570 // epoch and sequence_number
2571 for (int i = 0; i < 8; i++) {
2572 invalid.push_back(0);
2573 }
2574 // A one-byte fragment is invalid.
2575 invalid.push_back(0);
2576 invalid.push_back(1);
2577 // Arbitrary contents.
2578 invalid.push_back(0);
2579 } else {
2580 invalid = {'i', 'n', 'v', 'a', 'l', 'i', 'd'};
2581 }
2582 bssl::UniquePtr<BIO> rbio(
2583 BIO_new_mem_buf(invalid.data(), invalid.size()));
2584 ASSERT_TRUE(rbio);
2585 SSL_set0_rbio(ssl.get(), rbio.release());
2586
2587 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2588 ASSERT_TRUE(mem);
2589 SSL_set0_wbio(ssl.get(), bssl::UpRef(mem).release());
2590
2591 // The handshake should fail.
2592 EXPECT_EQ(-1, SSL_do_handshake(ssl.get()));
2593 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2594 uint32_t err = ERR_get_error();
2595
2596 // |ssl| should have written an alert (and, in the client's case, a
2597 // ClientHello) to the transport.
2598 const uint8_t *unused;
2599 size_t len;
2600 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2601 EXPECT_NE(0u, len);
2602 EXPECT_TRUE(BIO_reset(mem.get()));
2603
2604 // Writing should fail, with the same error as the handshake.
2605 EXPECT_EQ(-1, SSL_write(ssl.get(), "a", 1));
2606 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2607 EXPECT_EQ(err, ERR_get_error());
2608
2609 // Nothing should be written to the transport.
2610 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2611 EXPECT_EQ(0u, len);
2612 }
2613}
2614
2615// Test that, after seeing TLS 1.2 in response to early data, |SSL_write|
2616// continues to report |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. See
2617// https://crbug.com/1078515.
2618TEST(SSLTest, WriteAfterWrongVersionOnEarlyData) {
2619 // Set up some 0-RTT-enabled contexts.
2620 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2621 bssl::UniquePtr<SSL_CTX> server_ctx =
2622 CreateContextWithTestCertificate(TLS_method());
2623 ASSERT_TRUE(client_ctx);
2624 ASSERT_TRUE(server_ctx);
2625 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
2626 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
2627 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2628 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2629
2630 // Get an early-data-capable session.
2631 bssl::UniquePtr<SSL_SESSION> session =
2632 CreateClientSession(client_ctx.get(), server_ctx.get());
2633 ASSERT_TRUE(session);
2634 EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
2635
2636 // Offer the session to the server, but now the server speaks TLS 1.2.
2637 bssl::UniquePtr<SSL> client, server;
2638 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2639 server_ctx.get()));
2640 SSL_set_session(client.get(), session.get());
2641 EXPECT_TRUE(SSL_set_max_proto_version(server.get(), TLS1_2_VERSION));
2642
2643 // The client handshake initially succeeds in the early data state.
2644 EXPECT_EQ(1, SSL_do_handshake(client.get()));
2645 EXPECT_TRUE(SSL_in_early_data(client.get()));
2646
2647 // The server processes the ClientHello and negotiates TLS 1.2.
2648 EXPECT_EQ(-1, SSL_do_handshake(server.get()));
2649 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server.get(), -1));
2650 EXPECT_EQ(TLS1_2_VERSION, SSL_version(server.get()));
2651
2652 // Capture the client's output.
2653 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2654 ASSERT_TRUE(mem);
2655 SSL_set0_wbio(client.get(), bssl::UpRef(mem).release());
2656
2657 // The client processes the ServerHello and fails.
2658 EXPECT_EQ(-1, SSL_do_handshake(client.get()));
2659 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2660 uint32_t err = ERR_get_error();
2661 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2662 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2663
2664 // The client should have written an alert to the transport.
2665 const uint8_t *unused;
2666 size_t len;
2667 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2668 EXPECT_NE(0u, len);
2669 EXPECT_TRUE(BIO_reset(mem.get()));
2670
2671 // Writing should fail, with the same error as the handshake.
2672 EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
2673 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2674 err = ERR_get_error();
2675 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2676 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2677
2678 // Nothing should be written to the transport.
2679 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2680 EXPECT_EQ(0u, len);
2681}
2682
David Benjaminf0d8e222017-02-04 10:58:26 -05002683TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002684 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002685 bssl::UniquePtr<SSL_CTX> server_ctx =
2686 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002687 ASSERT_TRUE(client_ctx);
2688 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002689
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002690 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002691 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002692 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002693
2694 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002695 bssl::UniquePtr<SSL_SESSION> session1 =
2696 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002697 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002698
David Benjamina3a71e92018-06-29 13:24:45 -04002699 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002700
Steven Valdez87eab492016-06-27 16:34:59 -04002701 uint8_t *s0_bytes, *s1_bytes;
2702 size_t s0_len, s1_len;
2703
David Benjaminf0d8e222017-02-04 10:58:26 -05002704 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002705 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002706
David Benjaminf0d8e222017-02-04 10:58:26 -05002707 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002708 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002709
David Benjamin7d7554b2017-02-04 11:48:59 -05002710 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002711}
David Benjamin686bb192016-05-10 15:15:41 -04002712
David Benjaminf0d8e222017-02-04 10:58:26 -05002713static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002714 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002715 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2716 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002717
2718 // The wrapper BIOs are always equal when fds are equal, even if set
2719 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002720 if (rfd == wfd) {
2721 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002722 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002723}
2724
David Benjaminf0d8e222017-02-04 10:58:26 -05002725TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002726 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002727 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002728
2729 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002730 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002731 ASSERT_TRUE(ssl);
2732 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2733 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2734 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002735
2736 // Test setting the same FD.
2737 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002738 ASSERT_TRUE(ssl);
2739 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2740 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002741
2742 // Test setting the same FD one side at a time.
2743 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002744 ASSERT_TRUE(ssl);
2745 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2746 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2747 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002748
2749 // Test setting the same FD in the other order.
2750 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002751 ASSERT_TRUE(ssl);
2752 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2753 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2754 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002755
David Benjamin5c0fb882016-06-14 14:03:51 -04002756 // Test changing the read FD partway through.
2757 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002758 ASSERT_TRUE(ssl);
2759 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2760 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2761 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002762
2763 // Test changing the write FD partway through.
2764 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002765 ASSERT_TRUE(ssl);
2766 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2767 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2768 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002769
2770 // Test a no-op change to the read FD partway through.
2771 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002772 ASSERT_TRUE(ssl);
2773 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2774 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2775 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002776
2777 // Test a no-op change to the write FD partway through.
2778 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002779 ASSERT_TRUE(ssl);
2780 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2781 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2782 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002783
2784 // ASan builds will implicitly test that the internal |BIO| reference-counting
2785 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002786}
2787
David Benjaminf0d8e222017-02-04 10:58:26 -05002788TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002789 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002790 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002791
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002792 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2793 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002794 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002795 ASSERT_TRUE(ssl);
2796 ASSERT_TRUE(bio1);
2797 ASSERT_TRUE(bio2);
2798 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002799
2800 // SSL_set_bio takes one reference when the parameters are the same.
2801 BIO_up_ref(bio1.get());
2802 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2803
2804 // Repeating the call does nothing.
2805 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2806
2807 // It takes one reference each when the parameters are different.
2808 BIO_up_ref(bio2.get());
2809 BIO_up_ref(bio3.get());
2810 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2811
2812 // Repeating the call does nothing.
2813 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2814
2815 // It takes one reference when changing only wbio.
2816 BIO_up_ref(bio1.get());
2817 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2818
2819 // It takes one reference when changing only rbio and the two are different.
2820 BIO_up_ref(bio3.get());
2821 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2822
2823 // If setting wbio to rbio, it takes no additional references.
2824 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2825
2826 // From there, wbio may be switched to something else.
2827 BIO_up_ref(bio1.get());
2828 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2829
2830 // If setting rbio to wbio, it takes no additional references.
2831 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2832
2833 // From there, rbio may be switched to something else, but, for historical
2834 // reasons, it takes a reference to both parameters.
2835 BIO_up_ref(bio1.get());
2836 BIO_up_ref(bio2.get());
2837 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2838
2839 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2840 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002841}
2842
David Benjamin25490f22016-07-14 00:22:54 -04002843static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2844
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002845TEST_P(SSLVersionTest, GetPeerCertificate) {
2846 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002847
David Benjamin0fef3052016-11-18 15:11:10 +09002848 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002849 SSL_CTX_set_verify(client_ctx_.get(),
2850 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2851 nullptr);
2852 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2853 SSL_CTX_set_verify(server_ctx_.get(),
2854 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2855 nullptr);
2856 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002857
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002858 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002859
David Benjamin0fef3052016-11-18 15:11:10 +09002860 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002861 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2862 ASSERT_TRUE(peer);
2863 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002864
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002865 peer.reset(SSL_get_peer_certificate(client_.get()));
2866 ASSERT_TRUE(peer);
2867 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002868
David Benjamine664a532017-07-20 20:19:36 -04002869 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002870 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002871 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2872 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2873 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002874
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002875 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2876 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2877 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002878}
2879
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002880TEST_P(SSLVersionTest, NoPeerCertificate) {
2881 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2882 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2883 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002884
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002885 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 // Server should not see a peer certificate.
2888 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2889 ASSERT_FALSE(peer);
2890 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002891}
2892
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002893TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002894 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002895 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2896 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002897 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002898
2899 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2900 SHA256(cert_der, cert_der_len, cert_sha256);
2901
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2903
David Benjamin0fef3052016-11-18 15:11:10 +09002904 // Configure both client and server to accept any certificate, but the
2905 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002906 SSL_CTX_set_verify(client_ctx_.get(),
2907 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2908 nullptr);
2909 SSL_CTX_set_verify(server_ctx_.get(),
2910 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2911 nullptr);
2912 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2913 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2914 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002915
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002916 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002917
David Benjamin0fef3052016-11-18 15:11:10 +09002918 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002919 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2920 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002921
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002922 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002923 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002924
David Benjamin02de7bd2018-05-08 18:13:54 -04002925 const uint8_t *peer_sha256;
2926 size_t peer_sha256_len;
2927 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2928 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002929}
2930
David Benjamin737d2df2017-09-25 15:05:19 -04002931// Tests that our ClientHellos do not change unexpectedly. These are purely
2932// change detection tests. If they fail as part of an intentional ClientHello
2933// change, update the test vector.
2934TEST(SSLTest, ClientHello) {
2935 struct {
2936 uint16_t max_version;
2937 std::vector<uint8_t> expected;
2938 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002939 {TLS1_VERSION,
2940 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2944 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002945 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2946 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2947 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002948 {TLS1_1_VERSION,
2949 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2950 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2951 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2952 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2953 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002954 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2955 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2956 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002957 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002958 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002959 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2960 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002962 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002963 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002964 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2965 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2966 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2967 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2968 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2969 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002970 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2971 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002972 };
David Benjamin737d2df2017-09-25 15:05:19 -04002973
2974 for (const auto &t : kTests) {
2975 SCOPED_TRACE(t.max_version);
2976
2977 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2978 ASSERT_TRUE(ctx);
2979 // Our default cipher list varies by CPU capabilities, so manually place the
2980 // ChaCha20 ciphers in front.
2981 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002982 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2983 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2984
2985 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2986 ASSERT_TRUE(ssl);
2987 std::vector<uint8_t> client_hello;
2988 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2989
2990 // Zero the client_random.
2991 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2992 1 + 3 + // handshake message header
2993 2; // client_version
2994 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2995 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2996
2997 if (client_hello != t.expected) {
2998 ADD_FAILURE() << "ClientHellos did not match.";
2999 // Print the value manually so it is easier to update the test vector.
3000 for (size_t i = 0; i < client_hello.size(); i += 12) {
3001 printf(" %c", i == 0 ? '{' : ' ');
3002 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
3003 if (j > i) {
3004 printf(" ");
3005 }
3006 printf("0x%02x", client_hello[j]);
3007 if (j < client_hello.size() - 1) {
3008 printf(",");
3009 }
3010 }
3011 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07003012 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04003013 }
3014 printf("\n");
3015 }
3016 }
David Benjaminafc64de2016-07-19 17:12:41 +02003017 }
David Benjaminafc64de2016-07-19 17:12:41 +02003018}
3019
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003020static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
3021 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003022 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003023 ClientConfig config;
3024 config.session = session;
3025 EXPECT_TRUE(
3026 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04003027
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003028 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04003029
3030 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003031 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04003032}
3033
David Benjamin3c51d9b2016-11-01 17:50:42 -04003034static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
3035 SSL_CTX *server_ctx,
3036 SSL_SESSION *session) {
3037 g_last_session = nullptr;
3038 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
3039
3040 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003041 ClientConfig config;
3042 config.session = session;
3043 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05003044 config) ||
3045 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003046 fprintf(stderr, "Failed to connect client and server.\n");
3047 return nullptr;
3048 }
3049
3050 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
3051 fprintf(stderr, "Client and server were inconsistent.\n");
3052 return nullptr;
3053 }
3054
3055 if (!SSL_session_reused(client.get())) {
3056 fprintf(stderr, "Session was not reused.\n");
3057 return nullptr;
3058 }
3059
David Benjamin3c51d9b2016-11-01 17:50:42 -04003060 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
3061
3062 if (!g_last_session) {
3063 fprintf(stderr, "Client did not receive a renewed session.\n");
3064 return nullptr;
3065 }
3066 return std::move(g_last_session);
3067}
3068
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003069static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003070 bool changed) {
3071 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04003072 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003073 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
3074 if (changed) {
3075 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3076 } else {
3077 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003078 }
3079 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003080}
3081
David Benjamina933c382016-10-28 00:10:03 -04003082static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
3083 static const uint8_t kContext[] = {3};
3084
3085 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
3086 return SSL_TLSEXT_ERR_ALERT_FATAL;
3087 }
3088
3089 return SSL_TLSEXT_ERR_OK;
3090}
3091
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003092TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04003093 static const uint8_t kContext1[] = {1};
3094 static const uint8_t kContext2[] = {2};
3095
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003096 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3097 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04003098
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003099 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3100 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04003101
David Benjamin0fef3052016-11-18 15:11:10 +09003102 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003103 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3104 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04003105
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003106 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3107 session.get(),
3108 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003109
David Benjamin0fef3052016-11-18 15:11:10 +09003110 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003111 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
3112 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04003113
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003114 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3115 session.get(),
3116 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003117
David Benjamin0fef3052016-11-18 15:11:10 +09003118 // Change the session ID context back and install an SNI callback to switch
3119 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003120 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3121 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04003122
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003123 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003124 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04003125
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003126 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3127 session.get(),
3128 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003129
David Benjamin0fef3052016-11-18 15:11:10 +09003130 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003131 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003132 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003133 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003134 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3135 static const uint8_t kContext[] = {3};
3136
3137 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
3138 sizeof(kContext))) {
3139 return ssl_select_cert_error;
3140 }
3141
3142 return ssl_select_cert_success;
3143 });
David Benjamina933c382016-10-28 00:10:03 -04003144
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003145 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3146 session.get(),
3147 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003148}
3149
David Benjamin721e8b72016-08-03 13:13:17 -04003150static timeval g_current_time;
3151
3152static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
3153 *out_clock = g_current_time;
3154}
3155
David Benjamin17b30832017-01-28 14:00:32 -05003156static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
3157 out_clock->tv_sec = 1000;
3158 out_clock->tv_usec = 0;
3159}
3160
David Benjamin3c51d9b2016-11-01 17:50:42 -04003161static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
3162 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
3163 int encrypt) {
3164 static const uint8_t kZeros[16] = {0};
3165
3166 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05003167 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04003168 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05003169 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003170 return 0;
3171 }
3172
3173 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
3174 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
3175 return -1;
3176 }
3177
3178 // Returning two from the callback in decrypt mode renews the
3179 // session in TLS 1.2 and below.
3180 return encrypt ? 1 : 2;
3181}
3182
David Benjamin123db572016-11-03 16:59:25 -04003183static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04003184 const uint8_t *ticket;
3185 size_t ticket_len;
3186 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
3187 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04003188 return false;
3189 }
3190
David Benjaminaaef8332018-06-29 16:45:49 -04003191 const uint8_t *ciphertext = ticket + 16 + 16;
3192 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04003193 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
3194
David Benjamin9b63f292016-11-15 00:44:05 -05003195#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3196 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05003197 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05003198#else
3199 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04003200 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04003201 bssl::ScopedEVP_CIPHER_CTX ctx;
3202 int len1, len2;
3203 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
3204 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
3205 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
3206 return false;
3207 }
3208
3209 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05003210#endif
David Benjamin123db572016-11-03 16:59:25 -04003211
Adam Langley46db7af2017-02-01 15:49:37 -08003212 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
3213 if (!ssl_ctx) {
3214 return false;
3215 }
David Benjamin123db572016-11-03 16:59:25 -04003216 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08003217 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04003218 if (!server_session) {
3219 return false;
3220 }
3221
David Benjaminaaef8332018-06-29 16:45:49 -04003222 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04003223 return true;
3224}
3225
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003226TEST_P(SSLVersionTest, SessionTimeout) {
3227 for (bool server_test : {false, true}) {
3228 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04003229
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003230 ResetContexts();
3231 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3232 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3233
David Benjamin17b30832017-01-28 14:00:32 -05003234 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09003235 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04003236
David Benjamin17b30832017-01-28 14:00:32 -05003237 // We are willing to use a longer lifetime for TLS 1.3 sessions as
3238 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003239 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05003240 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
3241 : SSL_DEFAULT_SESSION_TIMEOUT;
3242
David Benjamin17b30832017-01-28 14:00:32 -05003243 // Both client and server must enforce session timeouts. We configure the
3244 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09003245 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003246 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3247 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003248 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003249 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
3250 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003251 }
3252
3253 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003254 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003255
3256 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003257 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3258 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09003259
3260 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05003261 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09003262
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003263 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3264 session.get(),
3265 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003266
3267 // Advance the clock one more second.
3268 g_current_time.tv_sec++;
3269
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003270 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3271 session.get(),
3272 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003273
3274 // Rewind the clock to before the session was minted.
3275 g_current_time.tv_sec = kStartTime - 1;
3276
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003277 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3278 session.get(),
3279 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003280
David Benjamin0fef3052016-11-18 15:11:10 +09003281 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05003282 time_t new_start_time = kStartTime + timeout - 10;
3283 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003284 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
3285 client_ctx_.get(), server_ctx_.get(), session.get());
3286 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09003287
3288 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003289 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003290
3291 // Check the sessions have timestamps measured from issuance.
3292 long session_time = 0;
3293 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003294 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003295 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003296 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003297 }
David Benjamin721e8b72016-08-03 13:13:17 -04003298
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003299 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003300
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003301 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003302 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3303 // lifetime TLS 1.3.
3304 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003305 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3306 new_session.get(),
3307 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003308
David Benjamin17b30832017-01-28 14:00:32 -05003309 // The new session expires after the new timeout.
3310 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003311 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3312 new_session.get(),
3313 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003314
3315 // Renew the session until it begins just past the auth timeout.
3316 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3317 while (new_start_time < auth_end_time - 1000) {
3318 // Get as close as possible to target start time.
3319 new_start_time =
3320 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3321 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003322 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003323 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003324 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003325 }
3326
3327 // Now the session's lifetime is bound by the auth timeout.
3328 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003329 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3330 new_session.get(),
3331 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003332
3333 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003334 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3335 new_session.get(),
3336 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003337 } else {
3338 // The new session is usable just before the old expiration.
3339 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003340 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3341 new_session.get(),
3342 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003343
3344 // Renewal does not extend the lifetime, so it is not usable beyond the
3345 // old expiration.
3346 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003347 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3348 new_session.get(),
3349 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003350 }
David Benjamin721e8b72016-08-03 13:13:17 -04003351 }
David Benjamin721e8b72016-08-03 13:13:17 -04003352}
3353
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003354TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003355 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3356 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003357 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003358 kTicketKeyLen));
3359 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3360}
3361
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003362TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003363 static const time_t kStartTime = 1001;
3364 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003365
David Benjaminc11ea9422017-08-29 16:33:21 -04003366 // We use session reuse as a proxy for ticket decryption success, hence
3367 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003368 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3369 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003370 std::numeric_limits<uint32_t>::max());
3371
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003372 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3373 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003374
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003375 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3376 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003377
David Benjamin1f0d54b2018-08-09 16:19:13 -05003378 // Initialize ticket_key with the current key and check that it was
3379 // initialized to something, not all zeros.
3380 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003381 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3382 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003383
David Benjaminc11ea9422017-08-29 16:33:21 -04003384 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003385 bssl::UniquePtr<SSL> client, server;
3386 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003387 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003388 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003389 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003390 session.get(), true /* reused */));
3391
David Benjaminc11ea9422017-08-29 16:33:21 -04003392 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003393 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003394 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003395 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003396 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003397 false /* NOT changed */));
3398
David Benjaminc11ea9422017-08-29 16:33:21 -04003399 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003400 g_current_time.tv_sec += 1;
3401 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003402 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3403 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3404 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003405
David Benjaminc11ea9422017-08-29 16:33:21 -04003406 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003407 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003408 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003409 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003410 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003411 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003412 false /* NOT changed */));
3413
David Benjaminc11ea9422017-08-29 16:33:21 -04003414 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003415 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003416 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003417 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003418 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3419 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003420
David Benjaminc11ea9422017-08-29 16:33:21 -04003421 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003422 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003423 new_session.get(), true /* reused */));
3424}
3425
David Benjamin0fc37ef2016-08-17 15:29:46 -04003426static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003427 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003428 SSL_set_SSL_CTX(ssl, ctx);
3429 return SSL_TLSEXT_ERR_OK;
3430}
3431
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003432TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003433 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003434 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003435 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003436 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003437
David Benjamin0fef3052016-11-18 15:11:10 +09003438 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3439 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003440
David Benjamin83a32122017-02-14 18:34:54 -05003441 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3442 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003444 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3445 ASSERT_TRUE(server_ctx2);
3446 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3447 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3448 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3449 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3450 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3451 sizeof(kOCSPResponse)));
3452 // Historically signing preferences would be lost in some cases with the
3453 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3454 // this doesn't happen when |version| is TLS 1.2, configure the private
3455 // key to only sign SHA-256.
3456 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3457 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003458
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003459 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3460 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003461
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003462 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3463 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003464
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003465 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003466
David Benjamin0fef3052016-11-18 15:11:10 +09003467 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003468 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3469 ASSERT_TRUE(peer);
3470 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003471
David Benjamin83a32122017-02-14 18:34:54 -05003472 // The client should have received |server_ctx2|'s SCT list.
3473 const uint8_t *data;
3474 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003475 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3476 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003477
3478 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003479 SSL_get0_ocsp_response(client_.get(), &data, &len);
3480 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003481}
3482
David Benjaminf0d8e222017-02-04 10:58:26 -05003483// Test that the early callback can swap the maximum version.
3484TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003485 bssl::UniquePtr<SSL_CTX> server_ctx =
3486 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003487 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003488 ASSERT_TRUE(server_ctx);
3489 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003490 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3491 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003492
David Benjaminf0d8e222017-02-04 10:58:26 -05003493 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003494 server_ctx.get(),
3495 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003496 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003497 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003498 }
3499
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003500 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003501 });
David Benjamin99620572016-08-30 00:35:36 -04003502
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003503 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003504 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003505 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003506 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003507}
3508
David Benjaminf0d8e222017-02-04 10:58:26 -05003509TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003510 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003511 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003512
David Benjaminf0d8e222017-02-04 10:58:26 -05003513 // Set valid TLS versions.
3514 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3515 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3516 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3517 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003518
David Benjaminf0d8e222017-02-04 10:58:26 -05003519 // Invalid TLS versions are rejected.
3520 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3521 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3522 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3523 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3524 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3525 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003526
David Benjaminf0d8e222017-02-04 10:58:26 -05003527 // Zero is the default version.
3528 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003529 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003530 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003531 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003532
David Benjamin9bb15f52018-06-26 00:07:40 -04003533 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003534 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003535 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04003536
David Benjamin9bb15f52018-06-26 00:07:40 -04003537 // SSL 3.0 is not available.
3538 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3539
David Benjamin2dc02042016-09-19 19:57:37 -04003540 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003541 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003542
David Benjaminf0d8e222017-02-04 10:58:26 -05003543 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3544 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
3545 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3546 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003547
David Benjaminf0d8e222017-02-04 10:58:26 -05003548 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3549 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3550 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3551 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3552 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3553 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3554 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3555 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003556
David Benjaminf0d8e222017-02-04 10:58:26 -05003557 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003558 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003559 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003560 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003561}
3562
David Benjamin458334a2016-12-15 13:53:25 -05003563static const char *GetVersionName(uint16_t version) {
3564 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003565 case TLS1_VERSION:
3566 return "TLSv1";
3567 case TLS1_1_VERSION:
3568 return "TLSv1.1";
3569 case TLS1_2_VERSION:
3570 return "TLSv1.2";
3571 case TLS1_3_VERSION:
3572 return "TLSv1.3";
3573 case DTLS1_VERSION:
3574 return "DTLSv1";
3575 case DTLS1_2_VERSION:
3576 return "DTLSv1.2";
3577 default:
3578 return "???";
3579 }
3580}
3581
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003582TEST_P(SSLVersionTest, Version) {
3583 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003584
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003585 EXPECT_EQ(SSL_version(client_.get()), version());
3586 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003587
David Benjamin458334a2016-12-15 13:53:25 -05003588 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003589 const char *version_name = GetVersionName(version());
3590 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3591 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003592
3593 // Test SSL_SESSION reports the same name.
3594 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003595 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003596 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003597 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3598 EXPECT_EQ(strcmp(version_name, client_name), 0);
3599 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003600}
3601
David Benjamin9ef31f02016-10-31 18:01:13 -04003602// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3603// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003604TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003605 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3606
David Benjamin9ef31f02016-10-31 18:01:13 -04003607 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003608 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3609 sizeof(kALPNProtos)),
3610 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003611
3612 // The ALPN callback does not fail the handshake on error, so have the
3613 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003614 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003615 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003616 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003617 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3618 unsigned in_len, void *arg) -> int {
3619 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3620 if (SSL_get_pending_cipher(ssl) != nullptr &&
3621 SSL_version(ssl) == state->first) {
3622 state->second = true;
3623 }
3624 return SSL_TLSEXT_ERR_NOACK;
3625 },
3626 &callback_state);
3627
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003628 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003629
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003630 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003631}
3632
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003633TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003634 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3635 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003636 if (version() == TLS1_3_VERSION) {
3637 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003638 }
3639
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003640 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003641 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003642
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003643 EXPECT_FALSE(SSL_session_reused(client_.get()));
3644 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003645
3646 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003647 ASSERT_TRUE(SSL_clear(client_.get()));
3648 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003649
3650 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003651 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003652
3653 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003654 EXPECT_TRUE(SSL_session_reused(client_.get()));
3655 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003656}
3657
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003658TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3659 shed_handshake_config_ = false;
3660 ASSERT_TRUE(Connect());
3661 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3662
3663 // Reset everything.
3664 ASSERT_TRUE(SSL_clear(client_.get()));
3665 ASSERT_TRUE(SSL_clear(server_.get()));
3666
3667 // Now enable shedding, and connect a second time.
3668 shed_handshake_config_ = true;
3669 ASSERT_TRUE(Connect());
3670 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3671
3672 // |SSL_clear| should now fail.
3673 ASSERT_FALSE(SSL_clear(client_.get()));
3674 ASSERT_FALSE(SSL_clear(server_.get()));
3675}
3676
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003677static bool ChainsEqual(STACK_OF(X509) * chain,
3678 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003679 if (sk_X509_num(chain) != expected.size()) {
3680 return false;
3681 }
3682
3683 for (size_t i = 0; i < expected.size(); i++) {
3684 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3685 return false;
3686 }
3687 }
3688
3689 return true;
3690}
3691
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003692TEST_P(SSLVersionTest, AutoChain) {
3693 cert_ = GetChainTestCertificate();
3694 ASSERT_TRUE(cert_);
3695 key_ = GetChainTestKey();
3696 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003697 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003698 ASSERT_TRUE(intermediate);
3699
3700 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3701 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003702
3703 // Configure both client and server to accept any certificate. Add
3704 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003705 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3706 intermediate.get()));
3707 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3708 intermediate.get()));
3709 SSL_CTX_set_verify(client_ctx_.get(),
3710 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3711 nullptr);
3712 SSL_CTX_set_verify(server_ctx_.get(),
3713 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3714 nullptr);
3715 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3716 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003717
3718 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003719 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003720
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003721 EXPECT_TRUE(
3722 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3723 EXPECT_TRUE(
3724 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003725
3726 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003727 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3728 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3729 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003730
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003731 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3732 {cert_.get(), intermediate.get()}));
3733 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3734 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003735
3736 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003737 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3738 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3739 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003740
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003741 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3742 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003743
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003744 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3745 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003746}
3747
David Benjamin48063c22017-01-01 23:56:36 -05003748static bool ExpectBadWriteRetry() {
3749 int err = ERR_get_error();
3750 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3751 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3752 char buf[ERR_ERROR_STRING_BUF_LEN];
3753 ERR_error_string_n(err, buf, sizeof(buf));
3754 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3755 return false;
3756 }
3757
3758 if (ERR_peek_error() != 0) {
3759 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3760 return false;
3761 }
3762
3763 return true;
3764}
3765
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003766TEST_P(SSLVersionTest, SSLWriteRetry) {
3767 if (is_dtls()) {
3768 return;
David Benjamin48063c22017-01-01 23:56:36 -05003769 }
3770
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003771 for (bool enable_partial_write : {false, true}) {
3772 SCOPED_TRACE(enable_partial_write);
3773
David Benjamin48063c22017-01-01 23:56:36 -05003774 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003775 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3776
3777 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003778
3779 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003780 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003781 }
3782
3783 // Write without reading until the buffer is full and we have an unfinished
3784 // write. Keep a count so we may reread it again later. "hello!" will be
3785 // written in two chunks, "hello" and "!".
3786 char data[] = "hello!";
3787 static const int kChunkLen = 5; // The length of "hello".
3788 unsigned count = 0;
3789 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003790 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003791 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003792 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3793 break;
David Benjamin48063c22017-01-01 23:56:36 -05003794 }
3795
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003796 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003797
3798 count++;
3799 }
3800
3801 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003802 ASSERT_EQ(
3803 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3804 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003805
3806 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003807 ASSERT_EQ(SSL_get_error(client_.get(),
3808 SSL_write(client_.get(), data, kChunkLen - 1)),
3809 SSL_ERROR_SSL);
3810 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003811
3812 // Retrying with a different buffer pointer is not legal.
3813 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003814 ASSERT_EQ(SSL_get_error(client_.get(),
3815 SSL_write(client_.get(), data2, kChunkLen)),
3816 SSL_ERROR_SSL);
3817 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003818
3819 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003820 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3821 ASSERT_EQ(SSL_get_error(client_.get(),
3822 SSL_write(client_.get(), data2, kChunkLen)),
3823 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003824
3825 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003826 ASSERT_EQ(SSL_get_error(client_.get(),
3827 SSL_write(client_.get(), data2, kChunkLen - 1)),
3828 SSL_ERROR_SSL);
3829 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003830
3831 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003832 ASSERT_EQ(SSL_get_error(client_.get(),
3833 SSL_write(client_.get(), data, kChunkLen + 1)),
3834 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003835
3836 // Drain the buffer.
3837 char buf[20];
3838 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003839 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3840 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003841 }
3842
3843 // Now that there is space, a retry with a larger buffer should flush the
3844 // pending record, skip over that many bytes of input (on assumption they
3845 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3846 // is set, this will complete in two steps.
3847 char data3[] = "_____!";
3848 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003849 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3850 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3851 } else {
3852 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003853 }
3854
3855 // Check the last write was correct. The data will be spread over two
3856 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003857 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3858 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3859 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3860 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003861 }
David Benjamin48063c22017-01-01 23:56:36 -05003862}
3863
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003864TEST_P(SSLVersionTest, RecordCallback) {
3865 for (bool test_server : {true, false}) {
3866 SCOPED_TRACE(test_server);
3867 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003868
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003869 bool read_seen = false;
3870 bool write_seen = false;
3871 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3872 size_t len, SSL *ssl) {
3873 if (cb_type != SSL3_RT_HEADER) {
3874 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003875 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003876
3877 // The callback does not report a version for records.
3878 EXPECT_EQ(0, cb_version);
3879
3880 if (is_write) {
3881 write_seen = true;
3882 } else {
3883 read_seen = true;
3884 }
3885
3886 // Sanity-check that the record header is plausible.
3887 CBS cbs;
3888 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3889 uint8_t type;
3890 uint16_t record_version, length;
3891 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3892 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003893 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003894 if (is_dtls()) {
3895 uint16_t epoch;
3896 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3897 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3898 ASSERT_TRUE(CBS_skip(&cbs, 6));
3899 }
3900 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3901 EXPECT_EQ(0u, CBS_len(&cbs));
3902 };
3903 using CallbackType = decltype(cb);
3904 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3905 SSL_CTX_set_msg_callback(
3906 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3907 size_t len, SSL *ssl, void *arg) {
3908 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3909 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3910 });
3911 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3912
3913 ASSERT_TRUE(Connect());
3914
3915 EXPECT_TRUE(read_seen);
3916 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003917 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003918}
3919
David Benjamina8614602017-09-06 15:40:19 -04003920TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003921 ClientConfig config;
3922 config.servername = "host1";
3923
3924 SSL_CTX_set_tlsext_servername_callback(
3925 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3926 // During the handshake, |SSL_get_servername| must match |config|.
3927 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3928 EXPECT_STREQ(config_p->servername.c_str(),
3929 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3930 return SSL_TLSEXT_ERR_OK;
3931 });
3932 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3933
3934 ASSERT_TRUE(Connect(config));
3935 // After the handshake, it must also be available.
3936 EXPECT_STREQ(config.servername.c_str(),
3937 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3938
3939 // Establish a session under host1.
3940 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3941 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3942 bssl::UniquePtr<SSL_SESSION> session =
3943 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3944
3945 // If the client resumes a session with a different name, |SSL_get_servername|
3946 // must return the new name.
3947 ASSERT_TRUE(session);
3948 config.session = session.get();
3949 config.servername = "host2";
3950 ASSERT_TRUE(Connect(config));
3951 EXPECT_STREQ(config.servername.c_str(),
3952 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3953}
3954
David Benjamin3d8f0802017-09-06 16:12:52 -04003955// Test that session cache mode bits are honored in the client session callback.
3956TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3957 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3958 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3959
3960 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3961 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3962
3963 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3964 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3965}
3966
Steven Valdez777a2392019-02-21 11:30:47 -05003967// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3968// NewSessionTickets are written post-handshake. Servers that block
3969// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3970// the buffer. Test that we do not do this.
3971TEST_P(SSLVersionTest, SmallBuffer) {
3972 // DTLS is a datagram protocol and requires packet-sized buffers.
3973 if (is_dtls()) {
3974 return;
3975 }
3976
3977 // Test both flushing NewSessionTickets with a zero-sized write and
3978 // non-zero-sized write.
3979 for (bool use_zero_write : {false, true}) {
3980 SCOPED_TRACE(use_zero_write);
3981
3982 g_last_session = nullptr;
3983 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3984 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3985
3986 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3987 server(SSL_new(server_ctx_.get()));
3988 ASSERT_TRUE(client);
3989 ASSERT_TRUE(server);
3990 SSL_set_connect_state(client.get());
3991 SSL_set_accept_state(server.get());
3992
3993 // Use a tiny buffer.
3994 BIO *bio1, *bio2;
3995 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3996
3997 // SSL_set_bio takes ownership.
3998 SSL_set_bio(client.get(), bio1, bio1);
3999 SSL_set_bio(server.get(), bio2, bio2);
4000
4001 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4002 if (version() >= TLS1_3_VERSION) {
4003 // The post-handshake ticket should not have been processed yet.
4004 EXPECT_FALSE(g_last_session);
4005 }
4006
4007 if (use_zero_write) {
4008 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
4009 EXPECT_TRUE(g_last_session);
4010 }
4011
4012 // Send some data from server to client. If |use_zero_write| is false, this
4013 // will also flush the NewSessionTickets.
4014 static const char kMessage[] = "hello world";
4015 char buf[sizeof(kMessage)];
4016 for (;;) {
4017 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
4018 int server_err = SSL_get_error(server.get(), server_ret);
4019 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
4020 int client_err = SSL_get_error(client.get(), client_ret);
4021
4022 // The server will write a single record, so every iteration should see
4023 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
4024 // iteration, where both will complete.
4025 if (server_ret > 0) {
4026 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
4027 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
4028 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
4029 break;
4030 }
4031
4032 ASSERT_EQ(server_ret, -1);
4033 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
4034 ASSERT_EQ(client_ret, -1);
4035 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4036 }
4037
4038 // The NewSessionTickets should have been flushed and processed.
4039 EXPECT_TRUE(g_last_session);
4040 }
4041}
4042
Adam Langleye1e78132017-01-31 15:24:31 -08004043TEST(SSLTest, AddChainCertHack) {
4044 // Ensure that we don't accidently break the hack that we have in place to
4045 // keep curl and serf happy when they use an |X509| even after transfering
4046 // ownership.
4047
4048 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4049 ASSERT_TRUE(ctx);
4050 X509 *cert = GetTestCertificate().release();
4051 ASSERT_TRUE(cert);
4052 SSL_CTX_add0_chain_cert(ctx.get(), cert);
4053
4054 // This should not trigger a use-after-free.
4055 X509_cmp(cert, cert);
4056}
4057
David Benjaminb2ff2622017-02-03 17:06:18 -05004058TEST(SSLTest, GetCertificate) {
4059 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4060 ASSERT_TRUE(ctx);
4061 bssl::UniquePtr<X509> cert = GetTestCertificate();
4062 ASSERT_TRUE(cert);
4063 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4064 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4065 ASSERT_TRUE(ssl);
4066
4067 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4068 ASSERT_TRUE(cert2);
4069 X509 *cert3 = SSL_get_certificate(ssl.get());
4070 ASSERT_TRUE(cert3);
4071
4072 // The old and new certificates must be identical.
4073 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4074 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
4075
4076 uint8_t *der = nullptr;
4077 long der_len = i2d_X509(cert.get(), &der);
4078 ASSERT_LT(0, der_len);
4079 bssl::UniquePtr<uint8_t> free_der(der);
4080
4081 uint8_t *der2 = nullptr;
4082 long der2_len = i2d_X509(cert2, &der2);
4083 ASSERT_LT(0, der2_len);
4084 bssl::UniquePtr<uint8_t> free_der2(der2);
4085
4086 uint8_t *der3 = nullptr;
4087 long der3_len = i2d_X509(cert3, &der3);
4088 ASSERT_LT(0, der3_len);
4089 bssl::UniquePtr<uint8_t> free_der3(der3);
4090
4091 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05004092 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4093 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05004094}
4095
Adam Langleyd04ca952017-02-28 11:26:51 -08004096TEST(SSLTest, SetChainAndKeyMismatch) {
4097 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4098 ASSERT_TRUE(ctx);
4099
4100 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4101 ASSERT_TRUE(key);
4102 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4103 ASSERT_TRUE(leaf);
4104 std::vector<CRYPTO_BUFFER*> chain = {
4105 leaf.get(),
4106 };
4107
4108 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
4109 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
4110 key.get(), nullptr));
4111 ERR_clear_error();
4112}
4113
4114TEST(SSLTest, SetChainAndKey) {
4115 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4116 ASSERT_TRUE(client_ctx);
4117 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4118 ASSERT_TRUE(server_ctx);
4119
Adam Langley964256d2020-03-19 11:57:12 -07004120 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4121
Adam Langleyd04ca952017-02-28 11:26:51 -08004122 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4123 ASSERT_TRUE(key);
4124 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4125 ASSERT_TRUE(leaf);
4126 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4127 GetChainTestIntermediateBuffer();
4128 ASSERT_TRUE(intermediate);
4129 std::vector<CRYPTO_BUFFER*> chain = {
4130 leaf.get(), intermediate.get(),
4131 };
4132 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4133 chain.size(), key.get(), nullptr));
4134
Adam Langley964256d2020-03-19 11:57:12 -07004135 ASSERT_EQ(chain.size(),
4136 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4137
David Benjamin3a1dd462017-07-11 16:13:10 -04004138 SSL_CTX_set_custom_verify(
4139 client_ctx.get(), SSL_VERIFY_PEER,
4140 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4141 return ssl_verify_ok;
4142 });
Adam Langleyd04ca952017-02-28 11:26:51 -08004143
4144 bssl::UniquePtr<SSL> client, server;
4145 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004146 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08004147}
4148
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004149TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4150 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4151 ASSERT_TRUE(client_ctx);
4152 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4153 ASSERT_TRUE(server_ctx);
4154
4155 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4156 ASSERT_TRUE(key);
4157 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4158 ASSERT_TRUE(leaf);
4159 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4160 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4161 chain.size(), key.get(), nullptr));
4162
4163 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4164 // configuration, certificate verification should fail.
4165 bssl::UniquePtr<SSL> client, server;
4166 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4167 server_ctx.get()));
4168
4169 // Whereas with a verifier, the connection should succeed.
4170 SSL_CTX_set_custom_verify(
4171 client_ctx.get(), SSL_VERIFY_PEER,
4172 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4173 return ssl_verify_ok;
4174 });
4175 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4176 server_ctx.get()));
4177}
4178
4179TEST(SSLTest, CustomVerify) {
4180 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4181 ASSERT_TRUE(client_ctx);
4182 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4183 ASSERT_TRUE(server_ctx);
4184
4185 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4186 ASSERT_TRUE(key);
4187 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4188 ASSERT_TRUE(leaf);
4189 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4190 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4191 chain.size(), key.get(), nullptr));
4192
4193 SSL_CTX_set_custom_verify(
4194 client_ctx.get(), SSL_VERIFY_PEER,
4195 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4196 return ssl_verify_ok;
4197 });
4198
4199 bssl::UniquePtr<SSL> client, server;
4200 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4201 server_ctx.get()));
4202
4203 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4204 // connection.
4205 SSL_CTX_set_custom_verify(
4206 client_ctx.get(), SSL_VERIFY_PEER,
4207 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4208 return ssl_verify_invalid;
4209 });
4210
4211 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4212 server_ctx.get()));
4213
4214 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4215 // connection.
4216 SSL_CTX_set_custom_verify(
4217 client_ctx.get(), SSL_VERIFY_NONE,
4218 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4219 return ssl_verify_invalid;
4220 });
4221
4222 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4223 server_ctx.get()));
4224}
4225
David Benjamin71dfad42017-07-16 17:27:39 -04004226TEST(SSLTest, ClientCABuffers) {
4227 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4228 ASSERT_TRUE(client_ctx);
4229 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4230 ASSERT_TRUE(server_ctx);
4231
4232 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4233 ASSERT_TRUE(key);
4234 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4235 ASSERT_TRUE(leaf);
4236 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4237 GetChainTestIntermediateBuffer();
4238 ASSERT_TRUE(intermediate);
4239 std::vector<CRYPTO_BUFFER *> chain = {
4240 leaf.get(),
4241 intermediate.get(),
4242 };
4243 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4244 chain.size(), key.get(), nullptr));
4245
4246 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4247 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4248 ASSERT_TRUE(ca_name);
4249 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4250 sk_CRYPTO_BUFFER_new_null());
4251 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04004252 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04004253 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
4254
4255 // Configure client and server to accept all certificates.
4256 SSL_CTX_set_custom_verify(
4257 client_ctx.get(), SSL_VERIFY_PEER,
4258 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4259 return ssl_verify_ok;
4260 });
4261 SSL_CTX_set_custom_verify(
4262 server_ctx.get(), SSL_VERIFY_PEER,
4263 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4264 return ssl_verify_ok;
4265 });
4266
4267 bool cert_cb_called = false;
4268 SSL_CTX_set_cert_cb(
4269 client_ctx.get(),
4270 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04004271 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04004272 SSL_get0_server_requested_CAs(ssl);
4273 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
4274 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
4275 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
4276 CRYPTO_BUFFER_len(peer_name)));
4277 *reinterpret_cast<bool *>(arg) = true;
4278 return 1;
4279 },
4280 &cert_cb_called);
4281
4282 bssl::UniquePtr<SSL> client, server;
4283 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004284 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04004285 EXPECT_TRUE(cert_cb_called);
4286}
4287
David Benjamin91222b82017-03-09 20:10:56 -05004288// Configuring the empty cipher list, though an error, should still modify the
4289// configuration.
4290TEST(SSLTest, EmptyCipherList) {
4291 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4292 ASSERT_TRUE(ctx);
4293
4294 // Initially, the cipher list is not empty.
4295 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4296
4297 // Configuring the empty cipher list fails.
4298 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4299 ERR_clear_error();
4300
4301 // But the cipher list is still updated to empty.
4302 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4303}
4304
Adam Langley4c341d02017-03-08 19:33:21 -08004305// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4306// test |SSL_TICKET_AEAD_METHOD| can fail.
4307enum ssl_test_ticket_aead_failure_mode {
4308 ssl_test_ticket_aead_ok = 0,
4309 ssl_test_ticket_aead_seal_fail,
4310 ssl_test_ticket_aead_open_soft_fail,
4311 ssl_test_ticket_aead_open_hard_fail,
4312};
4313
4314struct ssl_test_ticket_aead_state {
4315 unsigned retry_count;
4316 ssl_test_ticket_aead_failure_mode failure_mode;
4317};
4318
4319static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4320 const CRYPTO_EX_DATA *from,
4321 void **from_d, int index,
4322 long argl, void *argp) {
4323 abort();
4324}
4325
4326static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4327 CRYPTO_EX_DATA *ad, int index,
4328 long argl, void *argp) {
4329 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4330 if (state == nullptr) {
4331 return;
4332 }
4333
4334 OPENSSL_free(state);
4335}
4336
4337static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4338static int g_ssl_test_ticket_aead_ex_index;
4339
4340static int ssl_test_ticket_aead_get_ex_index() {
4341 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4342 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4343 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4344 ssl_test_ticket_aead_ex_index_free);
4345 });
4346 return g_ssl_test_ticket_aead_ex_index;
4347}
4348
4349static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4350 return 1;
4351}
4352
4353static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4354 size_t max_out_len, const uint8_t *in,
4355 size_t in_len) {
4356 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4357 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4358
4359 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4360 max_out_len < in_len + 1) {
4361 return 0;
4362 }
4363
4364 OPENSSL_memmove(out, in, in_len);
4365 out[in_len] = 0xff;
4366 *out_len = in_len + 1;
4367
4368 return 1;
4369}
4370
4371static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4372 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4373 const uint8_t *in, size_t in_len) {
4374 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4375 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4376
4377 if (state->retry_count > 0) {
4378 state->retry_count--;
4379 return ssl_ticket_aead_retry;
4380 }
4381
4382 switch (state->failure_mode) {
4383 case ssl_test_ticket_aead_ok:
4384 break;
4385 case ssl_test_ticket_aead_seal_fail:
4386 // If |seal| failed then there shouldn't be any ticket to try and
4387 // decrypt.
4388 abort();
4389 break;
4390 case ssl_test_ticket_aead_open_soft_fail:
4391 return ssl_ticket_aead_ignore_ticket;
4392 case ssl_test_ticket_aead_open_hard_fail:
4393 return ssl_ticket_aead_error;
4394 }
4395
4396 if (in_len == 0 || in[in_len - 1] != 0xff) {
4397 return ssl_ticket_aead_ignore_ticket;
4398 }
4399
4400 if (max_out_len < in_len - 1) {
4401 return ssl_ticket_aead_error;
4402 }
4403
4404 OPENSSL_memmove(out, in, in_len - 1);
4405 *out_len = in_len - 1;
4406 return ssl_ticket_aead_success;
4407}
4408
4409static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4410 ssl_test_ticket_aead_max_overhead,
4411 ssl_test_ticket_aead_seal,
4412 ssl_test_ticket_aead_open,
4413};
4414
4415static void ConnectClientAndServerWithTicketMethod(
4416 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4417 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4418 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4419 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4420 ASSERT_TRUE(client);
4421 ASSERT_TRUE(server);
4422 SSL_set_connect_state(client.get());
4423 SSL_set_accept_state(server.get());
4424
4425 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4426 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4427 ASSERT_TRUE(state);
4428 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4429 state->retry_count = retry_count;
4430 state->failure_mode = failure_mode;
4431
4432 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4433 state));
4434
4435 SSL_set_session(client.get(), session);
4436
4437 BIO *bio1, *bio2;
4438 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4439
4440 // SSL_set_bio takes ownership.
4441 SSL_set_bio(client.get(), bio1, bio1);
4442 SSL_set_bio(server.get(), bio2, bio2);
4443
4444 if (CompleteHandshakes(client.get(), server.get())) {
4445 *out_client = std::move(client);
4446 *out_server = std::move(server);
4447 } else {
4448 out_client->reset();
4449 out_server->reset();
4450 }
4451}
4452
David Benjaminc9775322018-04-13 16:39:12 -04004453using TicketAEADMethodParam =
4454 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4455
Adam Langley4c341d02017-03-08 19:33:21 -08004456class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004457 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004458
4459TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004460 bssl::UniquePtr<SSL_CTX> server_ctx =
4461 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004462 ASSERT_TRUE(server_ctx);
4463 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4464 ASSERT_TRUE(client_ctx);
4465
4466 const uint16_t version = testing::get<0>(GetParam());
4467 const unsigned retry_count = testing::get<1>(GetParam());
4468 const ssl_test_ticket_aead_failure_mode failure_mode =
4469 testing::get<2>(GetParam());
4470
Adam Langley4c341d02017-03-08 19:33:21 -08004471 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4472 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4473 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4474 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4475
4476 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4477 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4478 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4479 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004480 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004481
4482 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4483
4484 bssl::UniquePtr<SSL> client, server;
4485 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4486 server_ctx.get(), retry_count,
4487 failure_mode, nullptr);
4488 switch (failure_mode) {
4489 case ssl_test_ticket_aead_ok:
4490 case ssl_test_ticket_aead_open_hard_fail:
4491 case ssl_test_ticket_aead_open_soft_fail:
4492 ASSERT_TRUE(client);
4493 break;
4494 case ssl_test_ticket_aead_seal_fail:
4495 EXPECT_FALSE(client);
4496 return;
4497 }
4498 EXPECT_FALSE(SSL_session_reused(client.get()));
4499 EXPECT_FALSE(SSL_session_reused(server.get()));
4500
Steven Valdez777a2392019-02-21 11:30:47 -05004501 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004502 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004503 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4504 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004505 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004506 switch (failure_mode) {
4507 case ssl_test_ticket_aead_ok:
4508 ASSERT_TRUE(client);
4509 EXPECT_TRUE(SSL_session_reused(client.get()));
4510 EXPECT_TRUE(SSL_session_reused(server.get()));
4511 break;
4512 case ssl_test_ticket_aead_seal_fail:
4513 abort();
4514 break;
4515 case ssl_test_ticket_aead_open_hard_fail:
4516 EXPECT_FALSE(client);
4517 break;
4518 case ssl_test_ticket_aead_open_soft_fail:
4519 ASSERT_TRUE(client);
4520 EXPECT_FALSE(SSL_session_reused(client.get()));
4521 EXPECT_FALSE(SSL_session_reused(server.get()));
4522 }
4523}
4524
David Benjaminc9775322018-04-13 16:39:12 -04004525std::string TicketAEADMethodParamToString(
4526 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4527 std::string ret = GetVersionName(std::get<0>(params.param));
4528 // GTest only allows alphanumeric characters and '_' in the parameter
4529 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4530 for (auto it = ret.begin(); it != ret.end();) {
4531 if (*it == '.' || *it == 'v') {
4532 it = ret.erase(it);
4533 } else {
4534 ++it;
4535 }
4536 }
4537 char retry_count[256];
4538 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
4539 ret += "_";
4540 ret += retry_count;
4541 ret += "Retries_";
4542 switch (std::get<2>(params.param)) {
4543 case ssl_test_ticket_aead_ok:
4544 ret += "OK";
4545 break;
4546 case ssl_test_ticket_aead_seal_fail:
4547 ret += "SealFail";
4548 break;
4549 case ssl_test_ticket_aead_open_soft_fail:
4550 ret += "OpenSoftFail";
4551 break;
4552 case ssl_test_ticket_aead_open_hard_fail:
4553 ret += "OpenHardFail";
4554 break;
4555 }
4556 return ret;
4557}
4558
David Benjaminbe7006a2019-04-09 18:05:02 -05004559INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004560 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004561 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4562 testing::Values(0, 1, 2),
4563 testing::Values(ssl_test_ticket_aead_ok,
4564 ssl_test_ticket_aead_seal_fail,
4565 ssl_test_ticket_aead_open_soft_fail,
4566 ssl_test_ticket_aead_open_hard_fail)),
4567 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004568
David Benjaminca743582017-06-15 17:51:35 -04004569TEST(SSLTest, SelectNextProto) {
4570 uint8_t *result;
4571 uint8_t result_len;
4572
4573 // If there is an overlap, it should be returned.
4574 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4575 SSL_select_next_proto(&result, &result_len,
4576 (const uint8_t *)"\1a\2bb\3ccc", 9,
4577 (const uint8_t *)"\1x\1y\1a\1z", 8));
4578 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4579
4580 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4581 SSL_select_next_proto(&result, &result_len,
4582 (const uint8_t *)"\1a\2bb\3ccc", 9,
4583 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4584 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4585
4586 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4587 SSL_select_next_proto(&result, &result_len,
4588 (const uint8_t *)"\1a\2bb\3ccc", 9,
4589 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4590 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4591
4592 // Peer preference order takes precedence over local.
4593 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4594 SSL_select_next_proto(&result, &result_len,
4595 (const uint8_t *)"\1a\2bb\3ccc", 9,
4596 (const uint8_t *)"\3ccc\2bb\1a", 9));
4597 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4598
4599 // If there is no overlap, return the first local protocol.
4600 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4601 SSL_select_next_proto(&result, &result_len,
4602 (const uint8_t *)"\1a\2bb\3ccc", 9,
4603 (const uint8_t *)"\1x\2yy\3zzz", 9));
4604 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4605
4606 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4607 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4608 (const uint8_t *)"\1x\2yy\3zzz", 9));
4609 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4610}
4611
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004612TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004613 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004614 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004615 ASSERT_TRUE(client_ctx);
4616 ASSERT_TRUE(server_ctx);
4617
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004618 bssl::UniquePtr<SSL> client, server;
4619 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004620 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004621
4622 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4623 std::vector<uint8_t> prefix(
4624 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004625 body(record.size()),
4626 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004627 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4628 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004629 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004630
4631 std::vector<uint8_t> sealed;
4632 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4633 sealed.insert(sealed.end(), body.begin(), body.end());
4634 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4635 std::vector<uint8_t> sealed_copy = sealed;
4636
4637 bssl::Span<uint8_t> plaintext;
4638 size_t record_len;
4639 uint8_t alert = 255;
4640 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4641 bssl::MakeSpan(sealed)),
4642 bssl::OpenRecordResult::kOK);
4643 EXPECT_EQ(record_len, sealed.size());
4644 EXPECT_EQ(plaintext, record);
4645 EXPECT_EQ(255, alert);
4646}
4647
4648TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004649 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004650 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004651 ASSERT_TRUE(client_ctx);
4652 ASSERT_TRUE(server_ctx);
4653
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004654 bssl::UniquePtr<SSL> client, server;
4655 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004656 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004657
4658 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4659 std::vector<uint8_t> record = plaintext;
4660 std::vector<uint8_t> prefix(
4661 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004662 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004663 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4664 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004665 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004666 record.insert(record.begin(), prefix.begin(), prefix.end());
4667 record.insert(record.end(), suffix.begin(), suffix.end());
4668
4669 bssl::Span<uint8_t> result;
4670 size_t record_len;
4671 uint8_t alert;
4672 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4673 bssl::MakeSpan(record)),
4674 bssl::OpenRecordResult::kOK);
4675 EXPECT_EQ(record_len, record.size());
4676 EXPECT_EQ(plaintext, result);
4677}
4678
4679TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004680 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004681 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004682 ASSERT_TRUE(client_ctx);
4683 ASSERT_TRUE(server_ctx);
4684
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004685 bssl::UniquePtr<SSL> client, server;
4686 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004687 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004688
4689 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4690 std::vector<uint8_t> record = plaintext;
4691 std::vector<uint8_t> prefix(
4692 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004693 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004694 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4695 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004696 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004697 record.insert(record.begin(), prefix.begin(), prefix.end());
4698 record.insert(record.end(), suffix.begin(), suffix.end());
4699 record.insert(record.end(), {5, 4, 3, 2, 1});
4700
4701 bssl::Span<uint8_t> result;
4702 size_t record_len;
4703 uint8_t alert;
4704 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4705 bssl::MakeSpan(record)),
4706 bssl::OpenRecordResult::kOK);
4707 EXPECT_EQ(record_len, record.size() - 5);
4708 EXPECT_EQ(plaintext, result);
4709}
4710
4711TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004712 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004713 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004714 ASSERT_TRUE(client_ctx);
4715 ASSERT_TRUE(server_ctx);
4716
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004717 bssl::UniquePtr<SSL> client, server;
4718 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004719 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004720
4721 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4722 std::vector<uint8_t> prefix(
4723 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004724 body(record.size()),
4725 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004726
4727 auto expect_err = []() {
4728 int err = ERR_get_error();
4729 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4730 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4731 ERR_clear_error();
4732 };
4733 EXPECT_FALSE(bssl::SealRecord(
4734 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004735 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004736 expect_err();
4737 EXPECT_FALSE(bssl::SealRecord(
4738 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004739 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004740 expect_err();
4741
4742 EXPECT_FALSE(
4743 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4744 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004745 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004746 expect_err();
4747 EXPECT_FALSE(
4748 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4749 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004750 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004751 expect_err();
4752
4753 EXPECT_FALSE(bssl::SealRecord(
4754 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004755 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004756 expect_err();
4757 EXPECT_FALSE(bssl::SealRecord(
4758 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004759 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004760 expect_err();
4761}
4762
David Benjamin617b8182017-08-29 15:33:10 -04004763// The client should gracefully handle no suitable ciphers being enabled.
4764TEST(SSLTest, NoCiphersAvailable) {
4765 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4766 ASSERT_TRUE(ctx);
4767
4768 // Configure |client_ctx| with a cipher list that does not intersect with its
4769 // version configuration.
4770 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4771 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4772 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4773
4774 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4775 ASSERT_TRUE(ssl);
4776 SSL_set_connect_state(ssl.get());
4777
4778 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4779 ASSERT_TRUE(rbio);
4780 ASSERT_TRUE(wbio);
4781 SSL_set0_rbio(ssl.get(), rbio.release());
4782 SSL_set0_wbio(ssl.get(), wbio.release());
4783
4784 int ret = SSL_do_handshake(ssl.get());
4785 EXPECT_EQ(-1, ret);
4786 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4787 uint32_t err = ERR_get_error();
4788 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4789 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4790}
4791
David Benjamina4bafd32017-10-03 15:06:29 -04004792TEST_P(SSLVersionTest, SessionVersion) {
4793 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4794 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4795
4796 bssl::UniquePtr<SSL_SESSION> session =
4797 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4798 ASSERT_TRUE(session);
4799 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4800
4801 // Sessions in TLS 1.3 and later should be single-use.
4802 EXPECT_EQ(version() == TLS1_3_VERSION,
4803 !!SSL_SESSION_should_be_single_use(session.get()));
4804
4805 // Making fake sessions for testing works.
4806 session.reset(SSL_SESSION_new(client_ctx_.get()));
4807 ASSERT_TRUE(session);
4808 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4809 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4810}
4811
David Benjaminfdb7a352017-10-12 17:34:18 -04004812TEST_P(SSLVersionTest, SSLPending) {
4813 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4814 ASSERT_TRUE(ssl);
4815 EXPECT_EQ(0, SSL_pending(ssl.get()));
4816
4817 ASSERT_TRUE(Connect());
4818 EXPECT_EQ(0, SSL_pending(client_.get()));
4819
4820 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4821 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4822 EXPECT_EQ(0, SSL_pending(client_.get()));
4823
4824 char buf[10];
4825 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4826 EXPECT_EQ(5, SSL_pending(client_.get()));
4827
4828 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4829 EXPECT_EQ(4, SSL_pending(client_.get()));
4830
4831 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4832 EXPECT_EQ(0, SSL_pending(client_.get()));
4833
4834 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4835 EXPECT_EQ(3, SSL_pending(client_.get()));
4836}
4837
David Benjamina031b612017-10-11 20:48:25 -04004838// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4839TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004840 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004841 ASSERT_TRUE(ctx);
4842 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4843 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4844
David Benjamina031b612017-10-11 20:48:25 -04004845 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4846
4847 bssl::UniquePtr<SSL> client, server;
4848 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4849
4850 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4851 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4852 return 0;
4853 });
4854
4855 // Send close_notify.
4856 EXPECT_EQ(0, SSL_shutdown(server.get()));
4857 EXPECT_EQ(0, SSL_shutdown(client.get()));
4858
4859 // Receive close_notify.
4860 EXPECT_EQ(1, SSL_shutdown(server.get()));
4861 EXPECT_EQ(1, SSL_shutdown(client.get()));
4862}
4863
David Benjamin6cc352e2017-11-02 17:21:39 -04004864TEST(SSLTest, SignatureAlgorithmProperties) {
4865 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4866 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4867 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4868
4869 EXPECT_EQ(EVP_PKEY_RSA,
4870 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4871 EXPECT_EQ(EVP_md5_sha1(),
4872 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4873 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4874
4875 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4876 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4877 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4878 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4879 EXPECT_FALSE(
4880 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4881
4882 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004883 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004884 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004885 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4886 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004887}
4888
Adam Langley85967952018-07-03 08:04:58 -07004889static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4890 size_t in_len) {
4891 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004892 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004893 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004894 }
4895 }
4896
4897 SSL_set_app_data(ssl, XORCompressFunc);
4898
Adam Langley85967952018-07-03 08:04:58 -07004899 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004900}
4901
Adam Langley85967952018-07-03 08:04:58 -07004902static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4903 size_t uncompressed_len, const uint8_t *in,
4904 size_t in_len) {
4905 if (in_len != uncompressed_len) {
4906 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004907 }
4908
4909 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004910 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4911 if (*out == nullptr) {
4912 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004913 }
4914
Adam Langley85967952018-07-03 08:04:58 -07004915 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004916 data[i] = in[i] ^ 0x55;
4917 }
4918
4919 SSL_set_app_data(ssl, XORDecompressFunc);
4920
Adam Langley85967952018-07-03 08:04:58 -07004921 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004922}
4923
4924TEST(SSLTest, CertCompression) {
4925 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004926 bssl::UniquePtr<SSL_CTX> server_ctx(
4927 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004928 ASSERT_TRUE(client_ctx);
4929 ASSERT_TRUE(server_ctx);
4930
Adam Langley0080d832018-06-07 16:39:49 -07004931 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4932 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4933 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4934 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4935 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4936 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4937
4938 bssl::UniquePtr<SSL> client, server;
4939 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4940 server_ctx.get()));
4941
4942 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4943 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4944}
4945
Adam Langleyddb57cf2018-01-26 09:17:53 -08004946void MoveBIOs(SSL *dest, SSL *src) {
4947 BIO *rbio = SSL_get_rbio(src);
4948 BIO_up_ref(rbio);
4949 SSL_set0_rbio(dest, rbio);
4950
4951 BIO *wbio = SSL_get_wbio(src);
4952 BIO_up_ref(wbio);
4953 SSL_set0_wbio(dest, wbio);
4954
4955 SSL_set0_rbio(src, nullptr);
4956 SSL_set0_wbio(src, nullptr);
4957}
4958
4959TEST(SSLTest, Handoff) {
4960 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4961 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004962 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4963 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004964 ASSERT_TRUE(client_ctx);
4965 ASSERT_TRUE(server_ctx);
4966 ASSERT_TRUE(handshaker_ctx);
4967
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004968 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4969 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004970 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004971 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004972 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004973 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004974
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004975 for (bool early_data : {false, true}) {
4976 SCOPED_TRACE(early_data);
4977 for (bool is_resume : {false, true}) {
4978 SCOPED_TRACE(is_resume);
4979 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004980 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4981 server_ctx.get()));
4982 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004983 if (is_resume) {
4984 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004985 SSL_set_session(client.get(), g_last_session.get());
4986 if (early_data) {
4987 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4988 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004989 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004990
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004991
4992 int client_ret = SSL_do_handshake(client.get());
4993 int client_err = SSL_get_error(client.get(), client_ret);
4994
4995 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004996 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004997 ASSERT_EQ(client_err, 0);
4998 EXPECT_TRUE(SSL_in_early_data(client.get()));
4999 // Attempt to write early data.
5000 byte_written = 43;
5001 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5002 } else {
5003 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5004 }
5005
5006 int server_ret = SSL_do_handshake(server.get());
5007 int server_err = SSL_get_error(server.get(), server_ret);
5008 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5009
5010 ScopedCBB cbb;
5011 Array<uint8_t> handoff;
5012 SSL_CLIENT_HELLO hello;
5013 ASSERT_TRUE(CBB_init(cbb.get(), 256));
5014 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5015 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5016
5017 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
5018 // Note split handshakes determines 0-RTT support, for both the current
5019 // handshake and newly-issued tickets, entirely by |handshaker|. There is
5020 // no need to call |SSL_set_early_data_enabled| on |server|.
5021 SSL_set_early_data_enabled(handshaker.get(), 1);
5022 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5023
5024 MoveBIOs(handshaker.get(), server.get());
5025
5026 int handshake_ret = SSL_do_handshake(handshaker.get());
5027 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5028 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5029
5030 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08005031 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005032 handshake_ret = SSL_do_handshake(handshaker.get());
5033 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5034 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5035
5036 ScopedCBB cbb_handback;
5037 Array<uint8_t> handback;
5038 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5039 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5040 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5041
5042 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
5043 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5044
5045 MoveBIOs(server2.get(), handshaker.get());
5046 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5047 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
5048
David Benjamin9b2cdb72021-04-01 23:21:53 -04005049 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005050 // In this case, one byte of early data has already been written above.
5051 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5052 } else {
5053 byte_written = 42;
5054 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5055 }
5056 uint8_t byte;
5057 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5058 EXPECT_EQ(byte_written, byte);
5059
5060 byte = 44;
5061 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5062 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5063 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005064 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005065 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08005066}
5067
5068TEST(SSLTest, HandoffDeclined) {
5069 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005070 bssl::UniquePtr<SSL_CTX> server_ctx(
5071 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005072 ASSERT_TRUE(client_ctx);
5073 ASSERT_TRUE(server_ctx);
5074
5075 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
5076 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5077
Adam Langleyddb57cf2018-01-26 09:17:53 -08005078 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005079 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5080 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005081
5082 int client_ret = SSL_do_handshake(client.get());
5083 int client_err = SSL_get_error(client.get(), client_ret);
5084 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5085
5086 int server_ret = SSL_do_handshake(server.get());
5087 int server_err = SSL_get_error(server.get(), server_ret);
5088 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5089
5090 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005091 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005092 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005093 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005094
5095 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5096
5097 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5098
5099 uint8_t byte = 42;
5100 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5101 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5102 EXPECT_EQ(42, byte);
5103
5104 byte = 43;
5105 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5106 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5107 EXPECT_EQ(43, byte);
5108}
5109
Adam Langley826ce152018-08-03 10:31:21 -07005110static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5111 std::string ret = "{";
5112
5113 for (uint16_t v : sigalgs) {
5114 if (ret.size() > 1) {
5115 ret += ", ";
5116 }
5117
5118 char buf[8];
5119 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5120 buf[sizeof(buf)-1] = 0;
5121 ret += std::string(buf);
5122 }
5123
5124 ret += "}";
5125 return ret;
5126}
5127
5128void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5129 Span<const uint16_t> actual) {
5130 bool matches = false;
5131 if (expected.size() == actual.size()) {
5132 matches = true;
5133
5134 for (size_t i = 0; i < expected.size(); i++) {
5135 if (expected[i] != actual[i]) {
5136 matches = false;
5137 break;
5138 }
5139 }
5140 }
5141
5142 if (!matches) {
5143 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5144 << " got: " << SigAlgsToString(actual);
5145 }
5146}
5147
5148TEST(SSLTest, SigAlgs) {
5149 static const struct {
5150 std::vector<int> input;
5151 bool ok;
5152 std::vector<uint16_t> expected;
5153 } kTests[] = {
5154 {{}, true, {}},
5155 {{1}, false, {}},
5156 {{1, 2, 3}, false, {}},
5157 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5158 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5159
5160 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5161 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5162 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5163 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5164 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5165 true,
5166 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5167 };
5168
5169 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5170
5171 unsigned n = 1;
5172 for (const auto &test : kTests) {
5173 SCOPED_TRACE(n++);
5174
5175 const bool ok =
5176 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5177 EXPECT_EQ(ok, test.ok);
5178
5179 if (!ok) {
5180 ERR_clear_error();
5181 }
5182
5183 if (!test.ok) {
5184 continue;
5185 }
5186
5187 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5188 }
5189}
5190
5191TEST(SSLTest, SigAlgsList) {
5192 static const struct {
5193 const char *input;
5194 bool ok;
5195 std::vector<uint16_t> expected;
5196 } kTests[] = {
5197 {"", false, {}},
5198 {":", false, {}},
5199 {"+", false, {}},
5200 {"RSA", false, {}},
5201 {"RSA+", false, {}},
5202 {"RSA+SHA256:", false, {}},
5203 {":RSA+SHA256:", false, {}},
5204 {":RSA+SHA256+:", false, {}},
5205 {"!", false, {}},
5206 {"\x01", false, {}},
5207 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5208 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5209
5210 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5211 {"RSA+SHA256:ed25519",
5212 true,
5213 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5214 {"ECDSA+SHA256:RSA+SHA512",
5215 true,
5216 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5217 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5218 true,
5219 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5220 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5221 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5222 };
5223
5224 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5225
5226 unsigned n = 1;
5227 for (const auto &test : kTests) {
5228 SCOPED_TRACE(n++);
5229
5230 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5231 EXPECT_EQ(ok, test.ok);
5232
5233 if (!ok) {
5234 if (test.ok) {
5235 ERR_print_errors_fp(stderr);
5236 }
5237 ERR_clear_error();
5238 }
5239
5240 if (!test.ok) {
5241 continue;
5242 }
5243
5244 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5245 }
5246}
5247
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005248TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5249 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5250 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5251
5252 // handoff is a handoff message that has been artificially modified to pretend
5253 // that only cipher 0x0A is supported. When it is applied to |server|, all
5254 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005255 //
5256 // To make a new one of these, try sticking this in the |Handoff| test above:
5257 //
5258 // hexdump(stderr, "", handoff.data(), handoff.size());
5259 // sed -e 's/\(..\)/0x\1, /g'
5260 //
5261 // and modify serialize_features() to emit only cipher 0x0A.
5262
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005263 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005264 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5265 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5266 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5267 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5268 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005269 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5270 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005271 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5272 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5273 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5274 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5275 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
5276 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5277 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005278 };
5279
5280 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5281 ASSERT_TRUE(
5282 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5283 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5284}
5285
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005286TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5287 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5288 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5289
5290 // handoff is a handoff message that has been artificially modified to pretend
5291 // that only one curve is supported. When it is applied to |server|, all
5292 // curves but that one should be removed.
5293 //
5294 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5295 // these.
5296 uint8_t handoff[] = {
5297 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5298 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5299 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5300 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5301 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5302 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5303 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5304 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5305 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5306 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5307 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5308 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5309 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5310 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5311 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5312 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5313 0x02, 0x00, 0x17,
5314 };
5315
5316 // The zero length means that the default list of groups is used.
5317 EXPECT_EQ(0u, server->config->supported_group_list.size());
5318 ASSERT_TRUE(
5319 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5320 EXPECT_EQ(1u, server->config->supported_group_list.size());
5321}
5322
Adam Langleyba9ad662018-12-17 13:59:38 -08005323TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5324 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5325 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005326 bssl::UniquePtr<SSL_CTX> server_ctx(
5327 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005328 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5329 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005330
5331 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5332 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5333 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5334
5335 bssl::UniquePtr<SSL> client, server;
5336 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5337 server_ctx.get()));
5338
5339 BIO *client_wbio = SSL_get_wbio(client.get());
5340 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5341 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5342 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5343 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5344 EXPECT_NE(0u, BIO_wpending(client_wbio));
5345}
5346
David Benjamin5869eb32018-07-17 00:59:45 -04005347TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5348 // Configure the server to request client certificates.
5349 SSL_CTX_set_custom_verify(
5350 server_ctx_.get(), SSL_VERIFY_PEER,
5351 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5352
5353 // Configure the client to reject the server certificate.
5354 SSL_CTX_set_custom_verify(
5355 client_ctx_.get(), SSL_VERIFY_PEER,
5356 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5357
5358 // cert_cb should not be called. Verification should fail first.
5359 SSL_CTX_set_cert_cb(client_ctx_.get(),
5360 [](SSL *ssl, void *arg) {
5361 ADD_FAILURE() << "cert_cb unexpectedly called";
5362 return 0;
5363 },
5364 nullptr);
5365
5366 bssl::UniquePtr<SSL> client, server;
5367 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5368 server_ctx_.get()));
5369}
5370
David Benjamin492c9aa2018-08-31 16:35:22 -05005371// Test that ticket-based sessions on the client get fake session IDs.
5372TEST_P(SSLVersionTest, FakeIDsForTickets) {
5373 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5374 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5375
5376 bssl::UniquePtr<SSL_SESSION> session =
5377 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5378 ASSERT_TRUE(session);
5379
5380 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5381 unsigned session_id_length;
5382 SSL_SESSION_get_id(session.get(), &session_id_length);
5383 EXPECT_NE(session_id_length, 0u);
5384}
5385
David Benjamin6c04bd12018-07-19 18:13:09 -04005386// These tests test multi-threaded behavior. They are intended to run with
5387// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005388#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005389TEST_P(SSLVersionTest, SessionCacheThreads) {
5390 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5391 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5392 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5393
5394 if (version() == TLS1_3_VERSION) {
5395 // Our TLS 1.3 implementation does not support stateful resumption.
5396 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5397 return;
5398 }
5399
5400 // Establish two client sessions to test with.
5401 bssl::UniquePtr<SSL_SESSION> session1 =
5402 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5403 ASSERT_TRUE(session1);
5404 bssl::UniquePtr<SSL_SESSION> session2 =
5405 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5406 ASSERT_TRUE(session2);
5407
5408 auto connect_with_session = [&](SSL_SESSION *session) {
5409 ClientConfig config;
5410 config.session = session;
5411 UniquePtr<SSL> client, server;
5412 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5413 server_ctx_.get(), config));
5414 };
5415
5416 // Resume sessions in parallel with establishing new ones.
5417 {
5418 std::vector<std::thread> threads;
5419 threads.emplace_back([&] { connect_with_session(nullptr); });
5420 threads.emplace_back([&] { connect_with_session(nullptr); });
5421 threads.emplace_back([&] { connect_with_session(session1.get()); });
5422 threads.emplace_back([&] { connect_with_session(session1.get()); });
5423 threads.emplace_back([&] { connect_with_session(session2.get()); });
5424 threads.emplace_back([&] { connect_with_session(session2.get()); });
5425 for (auto &thread : threads) {
5426 thread.join();
5427 }
5428 }
5429
5430 // Hit the maximum session cache size across multiple threads
5431 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5432 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5433 {
5434 std::vector<std::thread> threads;
5435 for (int i = 0; i < 4; i++) {
5436 threads.emplace_back([&]() {
5437 connect_with_session(nullptr);
5438 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5439 });
5440 }
5441 for (auto &thread : threads) {
5442 thread.join();
5443 }
5444 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5445 }
5446}
5447
5448TEST_P(SSLVersionTest, SessionTicketThreads) {
5449 for (bool renew_ticket : {false, true}) {
5450 SCOPED_TRACE(renew_ticket);
5451 ResetContexts();
5452 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5453 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5454 if (renew_ticket) {
5455 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5456 }
5457
5458 // Establish two client sessions to test with.
5459 bssl::UniquePtr<SSL_SESSION> session1 =
5460 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5461 ASSERT_TRUE(session1);
5462 bssl::UniquePtr<SSL_SESSION> session2 =
5463 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5464 ASSERT_TRUE(session2);
5465
5466 auto connect_with_session = [&](SSL_SESSION *session) {
5467 ClientConfig config;
5468 config.session = session;
5469 UniquePtr<SSL> client, server;
5470 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5471 server_ctx_.get(), config));
5472 };
5473
5474 // Resume sessions in parallel with establishing new ones.
5475 {
5476 std::vector<std::thread> threads;
5477 threads.emplace_back([&] { connect_with_session(nullptr); });
5478 threads.emplace_back([&] { connect_with_session(nullptr); });
5479 threads.emplace_back([&] { connect_with_session(session1.get()); });
5480 threads.emplace_back([&] { connect_with_session(session1.get()); });
5481 threads.emplace_back([&] { connect_with_session(session2.get()); });
5482 threads.emplace_back([&] { connect_with_session(session2.get()); });
5483 for (auto &thread : threads) {
5484 thread.join();
5485 }
5486 }
5487 }
5488}
5489
5490// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5491TEST(SSLTest, GetCertificateThreads) {
5492 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5493 ASSERT_TRUE(ctx);
5494 bssl::UniquePtr<X509> cert = GetTestCertificate();
5495 ASSERT_TRUE(cert);
5496 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5497
5498 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5499 // threads concurrently. It originally was an immutable operation. Now we
5500 // implement it with a thread-safe cache, so it is worth testing.
5501 X509 *cert2_thread;
5502 std::thread thread(
5503 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5504 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5505 thread.join();
5506
5507 EXPECT_EQ(cert2, cert2_thread);
5508 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5509}
David Benjamin4cce9552018-12-13 12:20:54 -06005510
5511// Functions which access properties on the negotiated session are thread-safe
5512// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5513// performing stateful resumption will share an underlying SSL_SESSION object,
5514// potentially across threads.
5515TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5516 if (version() == TLS1_3_VERSION) {
5517 // Our TLS 1.3 implementation does not support stateful resumption.
5518 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5519 return;
5520 }
5521
5522 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5523 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5524 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5525
5526 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5527 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5528
5529 // Configure mutual authentication, so we have more session state.
5530 SSL_CTX_set_custom_verify(
5531 client_ctx_.get(), SSL_VERIFY_PEER,
5532 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5533 SSL_CTX_set_custom_verify(
5534 server_ctx_.get(), SSL_VERIFY_PEER,
5535 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5536
5537 // Establish a client session to test with.
5538 bssl::UniquePtr<SSL_SESSION> session =
5539 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5540 ASSERT_TRUE(session);
5541
5542 // Resume with it twice.
5543 UniquePtr<SSL> ssls[4];
5544 ClientConfig config;
5545 config.session = session.get();
5546 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5547 server_ctx_.get(), config));
5548 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5549 server_ctx_.get(), config));
5550
5551 // Read properties in parallel.
5552 auto read_properties = [](const SSL *ssl) {
5553 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5554 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5555 EXPECT_TRUE(peer);
5556 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5557 EXPECT_TRUE(SSL_get_curve_id(ssl));
5558 };
5559
5560 std::vector<std::thread> threads;
5561 for (const auto &ssl_ptr : ssls) {
5562 const SSL *ssl = ssl_ptr.get();
5563 threads.emplace_back([=] { read_properties(ssl); });
5564 }
5565 for (auto &thread : threads) {
5566 thread.join();
5567 }
5568}
David Benjamina486c6c2019-03-28 18:32:38 -05005569#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005570
Steven Valdezc8e0f902018-07-14 11:23:01 -04005571constexpr size_t kNumQUICLevels = 4;
5572static_assert(ssl_encryption_initial < kNumQUICLevels,
5573 "kNumQUICLevels is wrong");
5574static_assert(ssl_encryption_early_data < kNumQUICLevels,
5575 "kNumQUICLevels is wrong");
5576static_assert(ssl_encryption_handshake < kNumQUICLevels,
5577 "kNumQUICLevels is wrong");
5578static_assert(ssl_encryption_application < kNumQUICLevels,
5579 "kNumQUICLevels is wrong");
5580
David Benjamin1e859052020-02-09 16:04:58 -05005581const char *LevelToString(ssl_encryption_level_t level) {
5582 switch (level) {
5583 case ssl_encryption_initial:
5584 return "initial";
5585 case ssl_encryption_early_data:
5586 return "early data";
5587 case ssl_encryption_handshake:
5588 return "handshake";
5589 case ssl_encryption_application:
5590 return "application";
5591 }
5592 return "<unknown>";
5593}
5594
Steven Valdezc8e0f902018-07-14 11:23:01 -04005595class MockQUICTransport {
5596 public:
David Benjamind6343572019-08-15 17:29:02 -04005597 enum class Role { kClient, kServer };
5598
5599 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005600 // The caller is expected to configure initial secrets.
5601 levels_[ssl_encryption_initial].write_secret = {1};
5602 levels_[ssl_encryption_initial].read_secret = {1};
5603 }
5604
5605 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5606
5607 bool has_alert() const { return has_alert_; }
5608 ssl_encryption_level_t alert_level() const { return alert_level_; }
5609 uint8_t alert() const { return alert_; }
5610
5611 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5612 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005613 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5614 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005615 }
5616
David Benjamin1e859052020-02-09 16:04:58 -05005617 bool HasReadSecret(ssl_encryption_level_t level) const {
5618 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005619 }
5620
David Benjamin1e859052020-02-09 16:04:58 -05005621 bool HasWriteSecret(ssl_encryption_level_t level) const {
5622 return !levels_[level].write_secret.empty();
5623 }
5624
David Benjamin5298ef92020-03-13 12:17:30 -04005625 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5626
David Benjamin1e859052020-02-09 16:04:58 -05005627 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5628 Span<const uint8_t> secret) {
5629 if (HasReadSecret(level)) {
5630 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5631 return false;
5632 }
5633
5634 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5635 ADD_FAILURE() << "Unexpected early data read secret";
5636 return false;
5637 }
5638
5639 ssl_encryption_level_t ack_level =
5640 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5641 if (!HasWriteSecret(ack_level)) {
5642 ADD_FAILURE() << LevelToString(level)
5643 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005644 return false;
5645 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005646
5647 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005648 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005649 return false;
5650 }
5651
David Benjamin1e859052020-02-09 16:04:58 -05005652 if (level != ssl_encryption_early_data &&
5653 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5654 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005655 return false;
5656 }
David Benjamind6343572019-08-15 17:29:02 -04005657
David Benjamin1e859052020-02-09 16:04:58 -05005658 levels_[level].read_secret.assign(secret.begin(), secret.end());
5659 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5660 return true;
5661 }
5662
5663 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5664 Span<const uint8_t> secret) {
5665 if (HasWriteSecret(level)) {
5666 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005667 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005668 }
David Benjamind6343572019-08-15 17:29:02 -04005669
David Benjamin1e859052020-02-09 16:04:58 -05005670 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5671 ADD_FAILURE() << "Unexpected early data write secret";
5672 return false;
5673 }
5674
5675 if (cipher == nullptr) {
5676 ADD_FAILURE() << "Unexpected null cipher";
5677 return false;
5678 }
5679
5680 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005681 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005682 return true;
5683 }
5684
5685 bool WriteHandshakeData(ssl_encryption_level_t level,
5686 Span<const uint8_t> data) {
5687 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005688 ADD_FAILURE() << LevelToString(level)
5689 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005690 return false;
5691 }
David Benjamin5298ef92020-03-13 12:17:30 -04005692
5693 // Although the levels are conceptually separate, BoringSSL finishes writing
5694 // data from a previous level before installing keys for the next level.
5695 if (!allow_out_of_order_writes_) {
5696 switch (level) {
5697 case ssl_encryption_early_data:
5698 ADD_FAILURE() << "unexpected handshake data at early data level";
5699 return false;
5700 case ssl_encryption_initial:
5701 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5702 ADD_FAILURE()
5703 << LevelToString(level)
5704 << " handshake data written after handshake keys installed";
5705 return false;
5706 }
5707 OPENSSL_FALLTHROUGH;
5708 case ssl_encryption_handshake:
5709 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5710 ADD_FAILURE()
5711 << LevelToString(level)
5712 << " handshake data written after application keys installed";
5713 return false;
5714 }
5715 OPENSSL_FALLTHROUGH;
5716 case ssl_encryption_application:
5717 break;
5718 }
5719 }
5720
Steven Valdezc8e0f902018-07-14 11:23:01 -04005721 levels_[level].write_data.insert(levels_[level].write_data.end(),
5722 data.begin(), data.end());
5723 return true;
5724 }
5725
5726 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5727 if (has_alert_) {
5728 ADD_FAILURE() << "duplicate alert sent";
5729 return false;
5730 }
5731
5732 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005733 ADD_FAILURE() << LevelToString(level)
5734 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005735 return false;
5736 }
5737
5738 has_alert_ = true;
5739 alert_level_ = level;
5740 alert_ = alert_value;
5741 return true;
5742 }
5743
5744 bool ReadHandshakeData(std::vector<uint8_t> *out,
5745 ssl_encryption_level_t level,
5746 size_t num = std::numeric_limits<size_t>::max()) {
5747 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005748 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005749 return false;
5750 }
5751 // The peer may not have configured any keys yet.
5752 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005753 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005754 return true;
5755 }
5756 // Check the peer computed the same key.
5757 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005758 ADD_FAILURE() << "peer write key does not match read key in level "
5759 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005760 return false;
5761 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005762 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005763 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005764 return false;
5765 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005766 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5767 num = std::min(num, peer_data->size());
5768 out->assign(peer_data->begin(), peer_data->begin() + num);
5769 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5770 return true;
5771 }
5772
5773 private:
David Benjamind6343572019-08-15 17:29:02 -04005774 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005775 MockQUICTransport *peer_ = nullptr;
5776
David Benjamin5298ef92020-03-13 12:17:30 -04005777 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005778 bool has_alert_ = false;
5779 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5780 uint8_t alert_ = 0;
5781
5782 struct Level {
5783 std::vector<uint8_t> write_data;
5784 std::vector<uint8_t> write_secret;
5785 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005786 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005787 };
5788 Level levels_[kNumQUICLevels];
5789};
5790
5791class MockQUICTransportPair {
5792 public:
David Benjamind6343572019-08-15 17:29:02 -04005793 MockQUICTransportPair()
5794 : client_(MockQUICTransport::Role::kClient),
5795 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005796 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005797 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005798 }
5799
5800 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005801 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005802 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005803 }
5804
5805 MockQUICTransport *client() { return &client_; }
5806 MockQUICTransport *server() { return &server_; }
5807
5808 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005809 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5810 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5811 return client_.PeerSecretsMatch(level) &&
5812 client_.HasWriteSecret(level) &&
5813 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005814 }
5815
5816 private:
5817 MockQUICTransport client_;
5818 MockQUICTransport server_;
5819};
5820
5821class QUICMethodTest : public testing::Test {
5822 protected:
5823 void SetUp() override {
5824 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005825 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005826 ASSERT_TRUE(client_ctx_);
5827 ASSERT_TRUE(server_ctx_);
5828
Steven Valdezc8e0f902018-07-14 11:23:01 -04005829 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5830 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5831 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5832 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005833
5834 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5835 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5836 sizeof(kALPNProtos)),
5837 0);
5838 SSL_CTX_set_alpn_select_cb(
5839 server_ctx_.get(),
5840 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5841 unsigned in_len, void *arg) -> int {
5842 return SSL_select_next_proto(
5843 const_cast<uint8_t **>(out), out_len, in, in_len,
5844 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5845 ? SSL_TLSEXT_ERR_OK
5846 : SSL_TLSEXT_ERR_NOACK;
5847 },
5848 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005849 }
5850
5851 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5852 return ex_data_.Get(ssl);
5853 }
5854
5855 static bool ProvideHandshakeData(
5856 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5857 MockQUICTransport *transport = TransportFromSSL(ssl);
5858 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5859 std::vector<uint8_t> data;
5860 return transport->ReadHandshakeData(&data, level, num) &&
5861 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5862 }
5863
David Benjamin5298ef92020-03-13 12:17:30 -04005864 void AllowOutOfOrderWrites() {
5865 allow_out_of_order_writes_ = true;
5866 }
5867
Steven Valdezc8e0f902018-07-14 11:23:01 -04005868 bool CreateClientAndServer() {
5869 client_.reset(SSL_new(client_ctx_.get()));
5870 server_.reset(SSL_new(server_ctx_.get()));
5871 if (!client_ || !server_) {
5872 return false;
5873 }
5874
5875 SSL_set_connect_state(client_.get());
5876 SSL_set_accept_state(server_.get());
5877
David Benjamind6343572019-08-15 17:29:02 -04005878 transport_.reset(new MockQUICTransportPair);
5879 ex_data_.Set(client_.get(), transport_->client());
5880 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005881 if (allow_out_of_order_writes_) {
5882 transport_->client()->AllowOutOfOrderWrites();
5883 transport_->server()->AllowOutOfOrderWrites();
5884 }
Nick Harper7c522992020-04-30 14:15:49 -07005885 static const uint8_t client_transport_params[] = {0};
5886 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5887 sizeof(client_transport_params)) ||
5888 !SSL_set_quic_transport_params(server_.get(),
5889 server_transport_params_.data(),
5890 server_transport_params_.size()) ||
5891 !SSL_set_quic_early_data_context(
5892 server_.get(), server_quic_early_data_context_.data(),
5893 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005894 return false;
5895 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005896 return true;
5897 }
5898
Nick Harper72cff812020-03-26 18:06:16 -07005899 enum class ExpectedError {
5900 kNoError,
5901 kClientError,
5902 kServerError,
5903 };
5904
David Benjamind6343572019-08-15 17:29:02 -04005905 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5906 // |server_| until each completes once. It returns true on success and false
5907 // on failure.
5908 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005909 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5910 }
5911
5912 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5913 // once. If |expect_client_error| is true, it will return true only if the
5914 // client handshake failed. Otherwise, it returns true if both handshakes
5915 // succeed and false otherwise.
5916 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005917 bool client_done = false, server_done = false;
5918 while (!client_done || !server_done) {
5919 if (!client_done) {
5920 if (!ProvideHandshakeData(client_.get())) {
5921 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5922 return false;
5923 }
5924 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005925 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005926 if (client_ret == 1) {
5927 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005928 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005929 if (expected_error == ExpectedError::kClientError) {
5930 return true;
5931 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005932 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5933 << client_err;
5934 return false;
David Benjamind6343572019-08-15 17:29:02 -04005935 }
5936 }
5937
5938 if (!server_done) {
5939 if (!ProvideHandshakeData(server_.get())) {
5940 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5941 return false;
5942 }
5943 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005944 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005945 if (server_ret == 1) {
5946 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005947 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005948 if (expected_error == ExpectedError::kServerError) {
5949 return true;
5950 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005951 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5952 << server_err;
5953 return false;
David Benjamind6343572019-08-15 17:29:02 -04005954 }
5955 }
5956 }
Nick Harper72cff812020-03-26 18:06:16 -07005957 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005958 }
5959
5960 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5961 g_last_session = nullptr;
5962 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5963 if (!CreateClientAndServer() ||
5964 !CompleteHandshakesForQUIC()) {
5965 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005966 }
5967
David Benjamind6343572019-08-15 17:29:02 -04005968 // The server sent NewSessionTicket messages in the handshake.
5969 if (!ProvideHandshakeData(client_.get()) ||
5970 !SSL_process_quic_post_handshake(client_.get())) {
5971 return nullptr;
5972 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005973
David Benjamind6343572019-08-15 17:29:02 -04005974 return std::move(g_last_session);
5975 }
5976
5977 void ExpectHandshakeSuccess() {
5978 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5979 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5980 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5981 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5982 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5983 EXPECT_FALSE(transport_->client()->has_alert());
5984 EXPECT_FALSE(transport_->server()->has_alert());
5985
5986 // SSL_do_handshake is now idempotent.
5987 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5988 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005989 }
5990
David Benjamin1e859052020-02-09 16:04:58 -05005991 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5992 // the test.
5993 SSL_QUIC_METHOD DefaultQUICMethod() {
5994 return SSL_QUIC_METHOD{
5995 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5996 FlushFlightCallback, SendAlertCallback,
5997 };
5998 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005999
David Benjamin1e859052020-02-09 16:04:58 -05006000 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6001 const SSL_CIPHER *cipher,
6002 const uint8_t *secret, size_t secret_len) {
6003 return TransportFromSSL(ssl)->SetReadSecret(
6004 level, cipher, MakeConstSpan(secret, secret_len));
6005 }
6006
6007 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6008 const SSL_CIPHER *cipher,
6009 const uint8_t *secret, size_t secret_len) {
6010 return TransportFromSSL(ssl)->SetWriteSecret(
6011 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006012 }
6013
David Benjamincc9d9352018-10-30 19:45:22 -05006014 static int AddHandshakeDataCallback(SSL *ssl,
6015 enum ssl_encryption_level_t level,
6016 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006017 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6018 return TransportFromSSL(ssl)->WriteHandshakeData(level,
6019 MakeConstSpan(data, len));
6020 }
6021
6022 static int FlushFlightCallback(SSL *ssl) { return 1; }
6023
6024 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6025 uint8_t alert) {
6026 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6027 return TransportFromSSL(ssl)->SendAlert(level, alert);
6028 }
6029
6030 bssl::UniquePtr<SSL_CTX> client_ctx_;
6031 bssl::UniquePtr<SSL_CTX> server_ctx_;
6032
6033 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04006034 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006035
6036 bssl::UniquePtr<SSL> client_;
6037 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04006038
Nick Harper7c522992020-04-30 14:15:49 -07006039 std::vector<uint8_t> server_transport_params_ = {1};
6040 std::vector<uint8_t> server_quic_early_data_context_ = {2};
6041
David Benjamin5298ef92020-03-13 12:17:30 -04006042 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006043};
6044
6045UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6046
David Benjaminfd863b62019-07-25 13:51:32 -04006047// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006048TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05006049 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006050
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006051 g_last_session = nullptr;
6052
6053 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6054 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006055 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6056 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04006057
Steven Valdezc8e0f902018-07-14 11:23:01 -04006058 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006059 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006060
David Benjamind6343572019-08-15 17:29:02 -04006061 ExpectHandshakeSuccess();
6062 EXPECT_FALSE(SSL_session_reused(client_.get()));
6063 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006064
6065 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006066 EXPECT_FALSE(g_last_session);
6067 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6068 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6069 EXPECT_TRUE(g_last_session);
6070
6071 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04006072 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006073 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6074 SSL_set_session(client_.get(), session.get());
6075
David Benjamind6343572019-08-15 17:29:02 -04006076 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006077
David Benjamind6343572019-08-15 17:29:02 -04006078 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006079 EXPECT_TRUE(SSL_session_reused(client_.get()));
6080 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006081}
6082
David Benjaminfd863b62019-07-25 13:51:32 -04006083// Test that HelloRetryRequest in QUIC works.
6084TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006085 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006086
6087 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6088 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6089
6090 // BoringSSL predicts the most preferred curve, so using different preferences
6091 // will trigger HelloRetryRequest.
6092 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6093 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
6094 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6095 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6096 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
6097 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6098
6099 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006100 ASSERT_TRUE(CompleteHandshakesForQUIC());
6101 ExpectHandshakeSuccess();
6102}
David Benjaminfd863b62019-07-25 13:51:32 -04006103
Nick Harpere32549e2020-05-06 14:27:11 -07006104// Test that the client does not send a legacy_session_id in the ClientHello.
6105TEST_F(QUICMethodTest, NoLegacySessionId) {
6106 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6107
6108 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6109 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6110 // Check that the session ID length is 0 in an early callback.
6111 SSL_CTX_set_select_certificate_cb(
6112 server_ctx_.get(),
6113 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6114 EXPECT_EQ(client_hello->session_id_len, 0u);
6115 return ssl_select_cert_success;
6116 });
6117
6118 ASSERT_TRUE(CreateClientAndServer());
6119 ASSERT_TRUE(CompleteHandshakesForQUIC());
6120
6121 ExpectHandshakeSuccess();
6122}
6123
David Benjamin1e859052020-02-09 16:04:58 -05006124// Test that, even in a 1-RTT handshake, the server installs keys at the right
6125// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6126TEST_F(QUICMethodTest, HalfRTTKeys) {
6127 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6128
6129 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6130 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6131 ASSERT_TRUE(CreateClientAndServer());
6132
6133 // The client sends ClientHello.
6134 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6135 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6136
6137 // The server reads ClientHello and sends ServerHello..Finished.
6138 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6139 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6140 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6141
6142 // At this point, the server has half-RTT write keys, but it cannot access
6143 // 1-RTT read keys until client Finished.
6144 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6145 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6146
6147 // Finish up the client and server handshakes.
6148 ASSERT_TRUE(CompleteHandshakesForQUIC());
6149
6150 // Both sides can now exchange 1-RTT data.
6151 ExpectHandshakeSuccess();
6152}
6153
David Benjamind6343572019-08-15 17:29:02 -04006154TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006155 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006156
6157 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6158 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6159 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6160 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6161 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6162
6163 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6164 ASSERT_TRUE(session);
6165
6166 ASSERT_TRUE(CreateClientAndServer());
6167 SSL_set_session(client_.get(), session.get());
6168
6169 // The client handshake should return immediately into the early data state.
6170 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6171 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6172 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006173 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006174
6175 // The server will consume the ClientHello and also enter the early data
6176 // state.
6177 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6178 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6179 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6180 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006181 // At this point, the server has half-RTT write keys, but it cannot access
6182 // 1-RTT read keys until client Finished.
6183 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6184 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006185
6186 // Finish up the client and server handshakes.
6187 ASSERT_TRUE(CompleteHandshakesForQUIC());
6188
6189 // Both sides can now exchange 1-RTT data.
6190 ExpectHandshakeSuccess();
6191 EXPECT_TRUE(SSL_session_reused(client_.get()));
6192 EXPECT_TRUE(SSL_session_reused(server_.get()));
6193 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6194 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6195 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6196 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006197
6198 // Finish handling post-handshake messages after the first 0-RTT resumption.
6199 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6200 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6201
6202 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6203 // accepted again.
6204 ASSERT_TRUE(CreateClientAndServer());
6205 SSL_set_session(client_.get(), g_last_session.get());
6206
6207 // The client handshake should return immediately into the early data state.
6208 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6209 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6210 // The transport should have keys for sending 0-RTT data.
6211 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6212
6213 // The server will consume the ClientHello and also enter the early data
6214 // state.
6215 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6216 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6217 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6218 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6219 // At this point, the server has half-RTT write keys, but it cannot access
6220 // 1-RTT read keys until client Finished.
6221 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6222 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6223
6224 // Finish up the client and server handshakes.
6225 ASSERT_TRUE(CompleteHandshakesForQUIC());
6226
6227 // Both sides can now exchange 1-RTT data.
6228 ExpectHandshakeSuccess();
6229 EXPECT_TRUE(SSL_session_reused(client_.get()));
6230 EXPECT_TRUE(SSL_session_reused(server_.get()));
6231 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6232 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6233 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6234 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6235 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6236 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006237}
6238
Nick Harper7c522992020-04-30 14:15:49 -07006239TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6240 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6241
6242 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6243 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6244 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6245 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6246 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6247
6248
6249 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6250 ASSERT_TRUE(session);
6251
Nick Harper85194322020-05-20 16:59:29 -07006252 ASSERT_TRUE(CreateClientAndServer());
6253 static const uint8_t new_context[] = {4};
6254 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6255 sizeof(new_context)));
6256 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006257
Nick Harper85194322020-05-20 16:59:29 -07006258 // The client handshake should return immediately into the early data
6259 // state.
6260 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6261 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6262 // The transport should have keys for sending 0-RTT data.
6263 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006264
Nick Harper85194322020-05-20 16:59:29 -07006265 // The server will consume the ClientHello, but it will not accept 0-RTT.
6266 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6267 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6268 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6269 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6270 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006271
Nick Harper85194322020-05-20 16:59:29 -07006272 // The client consumes the server response and signals 0-RTT rejection.
6273 for (;;) {
6274 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6275 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6276 int err = SSL_get_error(client_.get(), -1);
6277 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6278 break;
Nick Harper7c522992020-04-30 14:15:49 -07006279 }
Nick Harper85194322020-05-20 16:59:29 -07006280 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006281 }
Nick Harper85194322020-05-20 16:59:29 -07006282
6283 // As in TLS over TCP, 0-RTT rejection is sticky.
6284 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6285 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6286
6287 // Finish up the client and server handshakes.
6288 SSL_reset_early_data_reject(client_.get());
6289 ASSERT_TRUE(CompleteHandshakesForQUIC());
6290
6291 // Both sides can now exchange 1-RTT data.
6292 ExpectHandshakeSuccess();
6293 EXPECT_TRUE(SSL_session_reused(client_.get()));
6294 EXPECT_TRUE(SSL_session_reused(server_.get()));
6295 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6296 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6297 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6298 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6299}
6300
6301TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6302 server_quic_early_data_context_ = {};
6303 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6304
6305 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6306 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6307 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6308 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6309 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6310
6311 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6312 ASSERT_TRUE(session);
6313 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006314}
6315
David Benjamind6343572019-08-15 17:29:02 -04006316TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006317 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006318
6319 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6320 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6321 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6322 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6323 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6324
6325 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6326 ASSERT_TRUE(session);
6327
6328 for (bool reject_hrr : {false, true}) {
6329 SCOPED_TRACE(reject_hrr);
6330
6331 ASSERT_TRUE(CreateClientAndServer());
6332 if (reject_hrr) {
6333 // Configure the server to prefer P-256, which will reject 0-RTT via
6334 // HelloRetryRequest.
6335 int p256 = NID_X9_62_prime256v1;
6336 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6337 } else {
6338 // Disable 0-RTT on the server, so it will reject it.
6339 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006340 }
David Benjamind6343572019-08-15 17:29:02 -04006341 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006342
David Benjamind6343572019-08-15 17:29:02 -04006343 // The client handshake should return immediately into the early data state.
6344 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6345 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6346 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006347 EXPECT_TRUE(
6348 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006349
6350 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006351 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006352 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6353 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6354 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006355 EXPECT_FALSE(
6356 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006357
6358 // The client consumes the server response and signals 0-RTT rejection.
6359 for (;;) {
6360 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6361 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6362 int err = SSL_get_error(client_.get(), -1);
6363 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6364 break;
6365 }
6366 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006367 }
6368
David Benjamind6343572019-08-15 17:29:02 -04006369 // As in TLS over TCP, 0-RTT rejection is sticky.
6370 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6371 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6372
6373 // Finish up the client and server handshakes.
6374 SSL_reset_early_data_reject(client_.get());
6375 ASSERT_TRUE(CompleteHandshakesForQUIC());
6376
6377 // Both sides can now exchange 1-RTT data.
6378 ExpectHandshakeSuccess();
6379 EXPECT_TRUE(SSL_session_reused(client_.get()));
6380 EXPECT_TRUE(SSL_session_reused(server_.get()));
6381 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6382 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6383 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6384 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006385 }
David Benjaminfd863b62019-07-25 13:51:32 -04006386}
6387
David Benjaminee0716f2019-11-19 14:16:28 +08006388TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006389 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006390
6391 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6392 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6393 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6394 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6395 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6396 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6397
6398 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6399 ASSERT_TRUE(session);
6400
6401 ASSERT_TRUE(CreateClientAndServer());
6402 SSL_set_session(client_.get(), session.get());
6403
6404 // Configure the certificate (re)verification to never complete. The client
6405 // handshake should pause.
6406 SSL_set_custom_verify(
6407 client_.get(), SSL_VERIFY_PEER,
6408 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6409 return ssl_verify_retry;
6410 });
6411 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6412 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6413 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6414
6415 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006416 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006417
6418 // After the verification completes, the handshake progresses to the 0-RTT
6419 // point and releases keys.
6420 SSL_set_custom_verify(
6421 client_.get(), SSL_VERIFY_PEER,
6422 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6423 return ssl_verify_ok;
6424 });
6425 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6426 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006427 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006428}
6429
Steven Valdezc8e0f902018-07-14 11:23:01 -04006430// Test only releasing data to QUIC one byte at a time on request, to maximize
6431// state machine pauses. Additionally, test that existing asynchronous callbacks
6432// still work.
6433TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006434 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006435
6436 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6437 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6438 ASSERT_TRUE(CreateClientAndServer());
6439
6440 // Install an asynchronous certificate callback.
6441 bool cert_cb_ok = false;
6442 SSL_set_cert_cb(server_.get(),
6443 [](SSL *, void *arg) -> int {
6444 return *static_cast<bool *>(arg) ? 1 : -1;
6445 },
6446 &cert_cb_ok);
6447
6448 for (;;) {
6449 int client_ret = SSL_do_handshake(client_.get());
6450 if (client_ret != 1) {
6451 ASSERT_EQ(client_ret, -1);
6452 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6453 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6454 }
6455
6456 int server_ret = SSL_do_handshake(server_.get());
6457 if (server_ret != 1) {
6458 ASSERT_EQ(server_ret, -1);
6459 int ssl_err = SSL_get_error(server_.get(), server_ret);
6460 switch (ssl_err) {
6461 case SSL_ERROR_WANT_READ:
6462 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6463 break;
6464 case SSL_ERROR_WANT_X509_LOOKUP:
6465 ASSERT_FALSE(cert_cb_ok);
6466 cert_cb_ok = true;
6467 break;
6468 default:
6469 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6470 }
6471 }
6472
6473 if (client_ret == 1 && server_ret == 1) {
6474 break;
6475 }
6476 }
6477
David Benjamind6343572019-08-15 17:29:02 -04006478 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006479}
6480
6481// Test buffering write data until explicit flushes.
6482TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006483 AllowOutOfOrderWrites();
6484
Steven Valdezc8e0f902018-07-14 11:23:01 -04006485 struct BufferedFlight {
6486 std::vector<uint8_t> data[kNumQUICLevels];
6487 };
6488 static UnownedSSLExData<BufferedFlight> buffered_flights;
6489
David Benjamincc9d9352018-10-30 19:45:22 -05006490 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6491 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006492 BufferedFlight *flight = buffered_flights.Get(ssl);
6493 flight->data[level].insert(flight->data[level].end(), data, data + len);
6494 return 1;
6495 };
6496
6497 auto flush_flight = [](SSL *ssl) -> int {
6498 BufferedFlight *flight = buffered_flights.Get(ssl);
6499 for (size_t level = 0; level < kNumQUICLevels; level++) {
6500 if (!flight->data[level].empty()) {
6501 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6502 static_cast<ssl_encryption_level_t>(level),
6503 flight->data[level])) {
6504 return 0;
6505 }
6506 flight->data[level].clear();
6507 }
6508 }
6509 return 1;
6510 };
6511
David Benjamin1e859052020-02-09 16:04:58 -05006512 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6513 quic_method.add_handshake_data = add_handshake_data;
6514 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006515
6516 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6517 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6518 ASSERT_TRUE(CreateClientAndServer());
6519
6520 BufferedFlight client_flight, server_flight;
6521 buffered_flights.Set(client_.get(), &client_flight);
6522 buffered_flights.Set(server_.get(), &server_flight);
6523
David Benjamind6343572019-08-15 17:29:02 -04006524 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006525
David Benjamind6343572019-08-15 17:29:02 -04006526 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006527}
6528
6529// Test that excess data at one level is rejected. That is, if a single
6530// |SSL_provide_quic_data| call included both ServerHello and
6531// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6532// key change.
6533TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006534 AllowOutOfOrderWrites();
6535
David Benjamincc9d9352018-10-30 19:45:22 -05006536 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6537 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006538 // Switch everything to the initial level.
6539 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6540 MakeConstSpan(data, len));
6541 };
6542
David Benjamin1e859052020-02-09 16:04:58 -05006543 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6544 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006545
6546 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6547 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6548 ASSERT_TRUE(CreateClientAndServer());
6549
6550 // Send the ClientHello and ServerHello through Finished.
6551 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6552 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6553 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6554 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6555 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6556
6557 // The client is still waiting for the ServerHello at initial
6558 // encryption.
6559 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6560
David Benjamincc9d9352018-10-30 19:45:22 -05006561 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6562 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006563 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6564
6565 // The client reads ServerHello successfully, but then rejects the buffered
6566 // EncryptedExtensions on key change.
6567 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6568 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6569 uint32_t err = ERR_get_error();
6570 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006571 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006572
David Benjamin1e859052020-02-09 16:04:58 -05006573 // The client sends an alert in response to this. The alert is sent at
6574 // handshake level because we install write secrets before read secrets and
6575 // the error is discovered when installing the read secret. (How to send
6576 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006577 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006578 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006579 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006580
David Benjamin5298ef92020-03-13 12:17:30 -04006581 // Sanity-check handshake secrets. The error is discovered while setting the
6582 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006583 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006584 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006585}
6586
6587// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6588TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006589 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006590
6591 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6592 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6593 ASSERT_TRUE(CreateClientAndServer());
6594
6595 // Send the ClientHello and ServerHello through Finished.
6596 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6597 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6598 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6599 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6600 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6601
6602 // The client is still waiting for the ServerHello at initial
6603 // encryption.
6604 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6605
6606 // Data cannot be provided at the next level.
6607 std::vector<uint8_t> data;
6608 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006609 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006610 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6611 data.data(), data.size()));
6612 ERR_clear_error();
6613
6614 // Progress to EncryptedExtensions.
6615 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6616 data.data(), data.size()));
6617 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6618 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6619 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6620
6621 // Data cannot be provided at the previous level.
6622 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006623 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006624 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6625 data.data(), data.size()));
6626}
6627
6628TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006629 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006630
6631 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6632 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6633 ASSERT_TRUE(CreateClientAndServer());
6634
6635 size_t limit =
6636 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6637 uint8_t b = 0;
6638 for (size_t i = 0; i < limit; i++) {
6639 ASSERT_TRUE(
6640 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6641 }
6642
6643 EXPECT_FALSE(
6644 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6645}
6646
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006647// Provide invalid post-handshake data.
6648TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006649 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006650
6651 g_last_session = nullptr;
6652
6653 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6654 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6655 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6656 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6657 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006658 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006659
6660 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6661 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006662 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6663 EXPECT_FALSE(transport_->client()->has_alert());
6664 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006665
6666 // Junk sent as part of post-handshake data should cause an error.
6667 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6668 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6669 kJunk, sizeof(kJunk)));
6670 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6671}
6672
Nick Harper80ddfc72020-03-11 18:26:31 -07006673static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6674 Span<const uint8_t> expected) {
6675 const uint8_t *received;
6676 size_t received_len;
6677 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6678 ASSERT_EQ(received_len, expected.size());
6679 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6680}
6681
6682TEST_F(QUICMethodTest, SetTransportParameters) {
6683 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6684 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6685 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6686
6687 ASSERT_TRUE(CreateClientAndServer());
6688 uint8_t kClientParams[] = {1, 2, 3, 4};
6689 uint8_t kServerParams[] = {5, 6, 7};
6690 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6691 sizeof(kClientParams)));
6692 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6693 sizeof(kServerParams)));
6694
6695 ASSERT_TRUE(CompleteHandshakesForQUIC());
6696 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6697 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6698}
6699
6700TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6701 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6702 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6703 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6704
6705 ASSERT_TRUE(CreateClientAndServer());
6706 uint8_t kClientParams[] = {1, 2, 3, 4};
6707 static uint8_t kServerParams[] = {5, 6, 7};
6708 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6709 sizeof(kClientParams)));
6710 SSL_CTX_set_tlsext_servername_callback(
6711 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6712 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6713 sizeof(kServerParams)));
6714 return SSL_TLSEXT_ERR_OK;
6715 });
6716
6717 ASSERT_TRUE(CompleteHandshakesForQUIC());
6718 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6719 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6720}
6721
Nick Harper6bfd25c2020-03-30 17:15:19 -07006722TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6723 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6724
6725 g_last_session = nullptr;
6726
6727 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6728 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6729 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6730 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6731
6732 ASSERT_TRUE(CreateClientAndServer());
6733 ASSERT_TRUE(CompleteHandshakesForQUIC());
6734
6735 ExpectHandshakeSuccess();
6736 EXPECT_FALSE(SSL_session_reused(client_.get()));
6737 EXPECT_FALSE(SSL_session_reused(server_.get()));
6738
6739 // The server sent NewSessionTicket messages in the handshake.
6740 EXPECT_FALSE(g_last_session);
6741 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6742 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6743 EXPECT_TRUE(g_last_session);
6744
6745 // Pretend that g_last_session came from a TLS-over-TCP connection.
6746 g_last_session.get()->is_quic = false;
6747
6748 // Create a second connection and verify that resumption does not occur with
6749 // a session from a non-QUIC connection. This tests that the client does not
6750 // offer over QUIC a session believed to be received over TCP. The server
6751 // believes this is a QUIC session, so if the client offered the session, the
6752 // server would have resumed it.
6753 ASSERT_TRUE(CreateClientAndServer());
6754 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6755 SSL_set_session(client_.get(), session.get());
6756
6757 ASSERT_TRUE(CompleteHandshakesForQUIC());
6758 ExpectHandshakeSuccess();
6759 EXPECT_FALSE(SSL_session_reused(client_.get()));
6760 EXPECT_FALSE(SSL_session_reused(server_.get()));
6761}
6762
6763TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6764 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6765
6766 g_last_session = nullptr;
6767
6768 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6769 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6770 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6771 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6772
6773 ASSERT_TRUE(CreateClientAndServer());
6774 ASSERT_TRUE(CompleteHandshakesForQUIC());
6775
6776 ExpectHandshakeSuccess();
6777 EXPECT_FALSE(SSL_session_reused(client_.get()));
6778 EXPECT_FALSE(SSL_session_reused(server_.get()));
6779
6780 // The server sent NewSessionTicket messages in the handshake.
6781 EXPECT_FALSE(g_last_session);
6782 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6783 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6784 EXPECT_TRUE(g_last_session);
6785
6786 // Attempt a resumption with g_last_session using TLS_method.
6787 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6788 ASSERT_TRUE(client_ctx);
6789
6790 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6791
6792 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6793 server(SSL_new(server_ctx_.get()));
6794 ASSERT_TRUE(client);
6795 ASSERT_TRUE(server);
6796 SSL_set_connect_state(client.get());
6797 SSL_set_accept_state(server.get());
6798
6799 // The TLS-over-TCP client will refuse to resume with a quic session, so
6800 // mark is_quic = false to bypass the client check to test the server check.
6801 g_last_session.get()->is_quic = false;
6802 SSL_set_session(client.get(), g_last_session.get());
6803
6804 BIO *bio1, *bio2;
6805 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6806
6807 // SSL_set_bio takes ownership.
6808 SSL_set_bio(client.get(), bio1, bio1);
6809 SSL_set_bio(server.get(), bio2, bio2);
6810 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6811
6812 EXPECT_FALSE(SSL_session_reused(client.get()));
6813 EXPECT_FALSE(SSL_session_reused(server.get()));
6814}
6815
Nick Harper72cff812020-03-26 18:06:16 -07006816TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6817 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6818 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6819 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6820
6821 ASSERT_TRUE(CreateClientAndServer());
6822 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6823 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6824}
6825
6826TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6827 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6828 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6829 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6830
6831 ASSERT_TRUE(CreateClientAndServer());
6832 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6833 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6834}
6835
David Schinazi3d8b8c32021-01-14 11:25:49 -08006836TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6837 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6838 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6839 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6840
6841 ASSERT_TRUE(CreateClientAndServer());
6842 uint8_t kClientParams[] = {1, 2, 3, 4};
6843 uint8_t kServerParams[] = {5, 6, 7};
6844 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6845 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6846 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6847 sizeof(kClientParams)));
6848 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6849 sizeof(kServerParams)));
6850
6851 ASSERT_TRUE(CompleteHandshakesForQUIC());
6852 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6853 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6854}
6855
6856TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6857 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6858 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6859 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6860
6861 ASSERT_TRUE(CreateClientAndServer());
6862 uint8_t kClientParams[] = {1, 2, 3, 4};
6863 uint8_t kServerParams[] = {5, 6, 7};
6864 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6865 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6866 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6867 sizeof(kClientParams)));
6868 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6869 sizeof(kServerParams)));
6870
6871 ASSERT_TRUE(CompleteHandshakesForQUIC());
6872 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6873 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6874}
6875
6876TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6877 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6878 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6879 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6880
6881 ASSERT_TRUE(CreateClientAndServer());
6882 uint8_t kClientParams[] = {1, 2, 3, 4};
6883 uint8_t kServerParams[] = {5, 6, 7};
6884 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6885 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6886 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6887 sizeof(kClientParams)));
6888 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6889 sizeof(kServerParams)));
6890
6891 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6892}
6893
6894TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6895 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6896 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6897 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6898
6899 ASSERT_TRUE(CreateClientAndServer());
6900 uint8_t kClientParams[] = {1, 2, 3, 4};
6901 uint8_t kServerParams[] = {5, 6, 7};
6902 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6903 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6904 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6905 sizeof(kClientParams)));
6906 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6907 sizeof(kServerParams)));
6908
6909 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6910}
6911
David Benjaminc47bfce2021-01-20 17:10:32 -05006912// Test that the default QUIC code point is consistent with
6913// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6914// update the two values together.
6915TEST_F(QUICMethodTest, QuicCodePointDefault) {
6916 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6917 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6918 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6919 SSL_CTX_set_select_certificate_cb(
6920 server_ctx_.get(),
6921 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6922 const uint8_t *data;
6923 size_t len;
6924 if (!SSL_early_callback_ctx_extension_get(
6925 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6926 &len)) {
6927 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6928 return ssl_select_cert_error;
6929 }
6930 return ssl_select_cert_success;
6931 });
6932
6933 ASSERT_TRUE(CreateClientAndServer());
6934 ASSERT_TRUE(CompleteHandshakesForQUIC());
6935}
6936
Adam Langley7540cc22019-04-18 09:56:13 -07006937extern "C" {
6938int BORINGSSL_enum_c_type_test(void);
6939}
6940
6941TEST(SSLTest, EnumTypes) {
6942 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6943 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6944}
6945
David Benjaminb29e1e12019-05-06 14:44:46 -05006946TEST_P(SSLVersionTest, DoubleSSLError) {
6947 // Connect the inner SSL connections.
6948 ASSERT_TRUE(Connect());
6949
6950 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6951 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6952 ASSERT_TRUE(bio_method);
6953 ASSERT_TRUE(BIO_meth_set_read(
6954 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6955 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6956 int ret = SSL_read(ssl, out, len);
6957 int ssl_ret = SSL_get_error(ssl, ret);
6958 if (ssl_ret == SSL_ERROR_WANT_READ) {
6959 BIO_set_retry_read(bio);
6960 }
6961 return ret;
6962 }));
6963 ASSERT_TRUE(BIO_meth_set_write(
6964 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6965 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6966 int ret = SSL_write(ssl, in, len);
6967 int ssl_ret = SSL_get_error(ssl, ret);
6968 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6969 BIO_set_retry_write(bio);
6970 }
6971 return ret;
6972 }));
6973 ASSERT_TRUE(BIO_meth_set_ctrl(
6974 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6975 // |SSL| objects require |BIO_flush| support.
6976 if (cmd == BIO_CTRL_FLUSH) {
6977 return 1;
6978 }
6979 return 0;
6980 }));
6981
6982 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6983 ASSERT_TRUE(client_bio);
6984 BIO_set_data(client_bio.get(), client_.get());
6985 BIO_set_init(client_bio.get(), 1);
6986
6987 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6988 ASSERT_TRUE(server_bio);
6989 BIO_set_data(server_bio.get(), server_.get());
6990 BIO_set_init(server_bio.get(), 1);
6991
6992 // Wrap the inner connections in another layer of SSL.
6993 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6994 ASSERT_TRUE(client_outer);
6995 SSL_set_connect_state(client_outer.get());
6996 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6997 client_bio.release(); // |SSL_set_bio| takes ownership.
6998
6999 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7000 ASSERT_TRUE(server_outer);
7001 SSL_set_accept_state(server_outer.get());
7002 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7003 server_bio.release(); // |SSL_set_bio| takes ownership.
7004
7005 // Configure |client_outer| to reject the server certificate.
7006 SSL_set_custom_verify(
7007 client_outer.get(), SSL_VERIFY_PEER,
7008 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7009 return ssl_verify_invalid;
7010 });
7011
7012 for (;;) {
7013 int client_ret = SSL_do_handshake(client_outer.get());
7014 int client_err = SSL_get_error(client_outer.get(), client_ret);
7015 if (client_err != SSL_ERROR_WANT_READ &&
7016 client_err != SSL_ERROR_WANT_WRITE) {
7017 // The client handshake should terminate on a certificate verification
7018 // error.
7019 EXPECT_EQ(SSL_ERROR_SSL, client_err);
7020 uint32_t err = ERR_peek_error();
7021 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7022 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
7023 break;
7024 }
7025
7026 // Run the server handshake and continue.
7027 int server_ret = SSL_do_handshake(server_outer.get());
7028 int server_err = SSL_get_error(server_outer.get(), server_ret);
7029 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7030 server_err == SSL_ERROR_WANT_READ ||
7031 server_err == SSL_ERROR_WANT_WRITE);
7032 }
7033}
7034
David Benjamin1b819472020-06-09 14:01:02 -04007035TEST_P(SSLVersionTest, SameKeyResume) {
7036 uint8_t key[48];
7037 RAND_bytes(key, sizeof(key));
7038
7039 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7040 ASSERT_TRUE(server_ctx2);
7041 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7042 ASSERT_TRUE(
7043 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7044 ASSERT_TRUE(
7045 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7046
7047 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7048 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7049 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7050
7051 // Establish a session for |server_ctx_|.
7052 bssl::UniquePtr<SSL_SESSION> session =
7053 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7054 ASSERT_TRUE(session);
7055 ClientConfig config;
7056 config.session = session.get();
7057
7058 // Resuming with |server_ctx_| again works.
7059 bssl::UniquePtr<SSL> client, server;
7060 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7061 server_ctx_.get(), config));
7062 EXPECT_TRUE(SSL_session_reused(client.get()));
7063 EXPECT_TRUE(SSL_session_reused(server.get()));
7064
7065 // Resuming with |server_ctx2| also works.
7066 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7067 server_ctx2.get(), config));
7068 EXPECT_TRUE(SSL_session_reused(client.get()));
7069 EXPECT_TRUE(SSL_session_reused(server.get()));
7070}
7071
7072TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7073 uint8_t key1[48], key2[48];
7074 RAND_bytes(key1, sizeof(key1));
7075 RAND_bytes(key2, sizeof(key2));
7076
7077 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7078 ASSERT_TRUE(server_ctx2);
7079 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7080 ASSERT_TRUE(
7081 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7082 ASSERT_TRUE(
7083 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7084
7085 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7086 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7087 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7088
7089 // Establish a session for |server_ctx_|.
7090 bssl::UniquePtr<SSL_SESSION> session =
7091 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7092 ASSERT_TRUE(session);
7093 ClientConfig config;
7094 config.session = session.get();
7095
7096 // Resuming with |server_ctx_| again works.
7097 bssl::UniquePtr<SSL> client, server;
7098 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7099 server_ctx_.get(), config));
7100 EXPECT_TRUE(SSL_session_reused(client.get()));
7101 EXPECT_TRUE(SSL_session_reused(server.get()));
7102
7103 // Resuming with |server_ctx2| does not work.
7104 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7105 server_ctx2.get(), config));
7106 EXPECT_FALSE(SSL_session_reused(client.get()));
7107 EXPECT_FALSE(SSL_session_reused(server.get()));
7108}
7109
7110TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7111 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7112 ASSERT_TRUE(server_ctx2);
7113 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7114
7115 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7116 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7117 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7118
7119 // Establish a session for |server_ctx_|.
7120 bssl::UniquePtr<SSL_SESSION> session =
7121 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7122 ASSERT_TRUE(session);
7123 ClientConfig config;
7124 config.session = session.get();
7125
7126 // Resuming with |server_ctx_| again works.
7127 bssl::UniquePtr<SSL> client, server;
7128 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7129 server_ctx_.get(), config));
7130 EXPECT_TRUE(SSL_session_reused(client.get()));
7131 EXPECT_TRUE(SSL_session_reused(server.get()));
7132
7133 // Resuming with |server_ctx2| does not work.
7134 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7135 server_ctx2.get(), config));
7136 EXPECT_FALSE(SSL_session_reused(client.get()));
7137 EXPECT_FALSE(SSL_session_reused(server.get()));
7138}
7139
Adam Langley47cefed2021-05-26 13:36:40 -07007140Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7141 const SSL_SESSION *session = SSL_get_session(ssl);
7142 unsigned len;
7143 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7144 return MakeConstSpan(data, len);
7145}
7146
7147TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7148 // This checks that the session IDs at client and server match after a ticket
7149 // resumption. It's unclear whether this should be true, but Envoy depends
7150 // on it in their tests so this will give an early signal if we break it.
7151 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7152 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7153
7154 bssl::UniquePtr<SSL_SESSION> session =
7155 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7156
7157 bssl::UniquePtr<SSL> client, server;
7158 ClientConfig config;
7159 config.session = session.get();
7160 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7161 server_ctx_.get(), config));
7162 EXPECT_TRUE(SSL_session_reused(client.get()));
7163 EXPECT_TRUE(SSL_session_reused(server.get()));
7164
7165 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7166}
7167
David Benjamin0e7dbd52019-05-15 16:01:18 -04007168TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04007169 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007170 ASSERT_TRUE(ctx);
7171
David Benjamin0e7dbd52019-05-15 16:01:18 -04007172 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7173 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7174 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7175 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7176
7177 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007178 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007179 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04007180 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007181
7182 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7183
7184 // Write "hello" until the buffer is full, so |client| has a pending write.
7185 size_t num_writes = 0;
7186 for (;;) {
7187 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7188 if (ret != int(sizeof(kInput))) {
7189 ASSERT_EQ(-1, ret);
7190 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7191 break;
7192 }
7193 num_writes++;
7194 }
7195
7196 // Encrypt a HelloRequest.
7197 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7198#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7199 // Fuzzer-mode records are unencrypted.
7200 uint8_t record[5 + sizeof(in)];
7201 record[0] = SSL3_RT_HANDSHAKE;
7202 record[1] = 3;
7203 record[2] = 3; // TLS 1.2
7204 record[3] = 0;
7205 record[4] = sizeof(record) - 5;
7206 memcpy(record + 5, in, sizeof(in));
7207#else
7208 // Extract key material from |server|.
7209 static const size_t kKeyLen = 32;
7210 static const size_t kNonceLen = 12;
7211 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
7212 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
7213 ASSERT_TRUE(
7214 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
7215 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7216 Span<uint8_t> nonce =
7217 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7218
7219 uint8_t ad[13];
7220 uint64_t seq = SSL_get_write_sequence(server.get());
7221 for (size_t i = 0; i < 8; i++) {
7222 // The nonce is XORed with the sequence number.
7223 nonce[11 - i] ^= uint8_t(seq);
7224 ad[7 - i] = uint8_t(seq);
7225 seq >>= 8;
7226 }
7227
7228 ad[8] = SSL3_RT_HANDSHAKE;
7229 ad[9] = 3;
7230 ad[10] = 3; // TLS 1.2
7231 ad[11] = 0;
7232 ad[12] = sizeof(in);
7233
7234 uint8_t record[5 + sizeof(in) + 16];
7235 record[0] = SSL3_RT_HANDSHAKE;
7236 record[1] = 3;
7237 record[2] = 3; // TLS 1.2
7238 record[3] = 0;
7239 record[4] = sizeof(record) - 5;
7240
7241 ScopedEVP_AEAD_CTX aead;
7242 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7243 key.data(), key.size(),
7244 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7245 size_t len;
7246 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7247 sizeof(record) - 5, nonce.data(), nonce.size(),
7248 in, sizeof(in), ad, sizeof(ad)));
7249 ASSERT_EQ(sizeof(record) - 5, len);
7250#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7251
7252 ASSERT_EQ(int(sizeof(record)),
7253 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
7254
7255 // |SSL_read| should pick up the HelloRequest.
7256 uint8_t byte;
7257 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7258 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7259
7260 // Drain the data from the |client|.
7261 uint8_t buf[sizeof(kInput)];
7262 for (size_t i = 0; i < num_writes; i++) {
7263 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7264 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7265 }
7266
7267 // |client| should be able to finish the pending write and continue to write,
7268 // despite the paused HelloRequest.
7269 ASSERT_EQ(int(sizeof(kInput)),
7270 SSL_write(client.get(), kInput, sizeof(kInput)));
7271 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7272 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7273
7274 ASSERT_EQ(int(sizeof(kInput)),
7275 SSL_write(client.get(), kInput, sizeof(kInput)));
7276 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7277 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7278
7279 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7280 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7281 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7282
7283 ASSERT_TRUE(SSL_renegotiate(client.get()));
7284 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7285 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7286
7287 // We never renegotiate as a server.
7288 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7289 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7290 uint32_t err = ERR_get_error();
7291 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7292 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7293}
7294
David Benjaminf9e0cda2020-03-23 18:29:09 -04007295
7296TEST(SSLTest, CopyWithoutEarlyData) {
7297 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007298 bssl::UniquePtr<SSL_CTX> server_ctx(
7299 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007300 ASSERT_TRUE(client_ctx);
7301 ASSERT_TRUE(server_ctx);
7302
David Benjaminf9e0cda2020-03-23 18:29:09 -04007303 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7304 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7305 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7306 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7307
7308 bssl::UniquePtr<SSL_SESSION> session =
7309 CreateClientSession(client_ctx.get(), server_ctx.get());
7310 ASSERT_TRUE(session);
7311
7312 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007313 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007314 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7315 server_ctx.get()));
7316 SSL_set_session(client.get(), session.get());
7317 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007318 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7319 EXPECT_TRUE(SSL_in_early_data(client.get()));
7320
7321 // |SSL_SESSION_copy_without_early_data| should disable early data but
7322 // still resume the session.
7323 bssl::UniquePtr<SSL_SESSION> session2(
7324 SSL_SESSION_copy_without_early_data(session.get()));
7325 ASSERT_TRUE(session2);
7326 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007327 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7328 server_ctx.get()));
7329 SSL_set_session(client.get(), session2.get());
7330 SSL_set_early_data_enabled(client.get(), 1);
7331 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007332 EXPECT_TRUE(SSL_session_reused(client.get()));
7333 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7334 SSL_get_early_data_reason(client.get()));
7335
7336 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7337 // when passed an early-data-incapable session.
7338 bssl::UniquePtr<SSL_SESSION> session3(
7339 SSL_SESSION_copy_without_early_data(session2.get()));
7340 EXPECT_EQ(session2.get(), session3.get());
7341}
7342
Adam Langley53a17f52020-05-26 14:44:07 -07007343TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7344 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007345 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007346 bssl::UniquePtr<SSL_CTX> server_ctx(
7347 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007348 ASSERT_TRUE(client_ctx);
7349 ASSERT_TRUE(server_ctx);
7350 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7351 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7352 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7353 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007354
7355 bssl::UniquePtr<SSL> client, server;
7356 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7357 server_ctx.get()));
7358 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7359
7360 // Process a TLS 1.3 NewSessionTicket.
7361 static const uint8_t kTicket[] = {
7362 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7363 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7364 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7365 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7366 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7367 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7368 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7369 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7370 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7371 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7372 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7373 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7374 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7375 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7376 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7377 0x00, 0x00,
7378 };
7379 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7380 client.get(), kTicket, sizeof(kTicket)));
7381 ASSERT_TRUE(session);
7382 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7383
7384 uint8_t *session_buf = nullptr;
7385 size_t session_length = 0;
7386 ASSERT_TRUE(
7387 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7388 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7389 ASSERT_TRUE(session_buf);
7390 ASSERT_GT(session_length, 0u);
7391
7392 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7393 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7394 sizeof(kTicket)));
7395
7396 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7397 // handshake completes.
7398 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7399 ASSERT_TRUE(client2);
7400 SSL_set_connect_state(client2.get());
7401 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7402 sizeof(kTicket)));
7403}
7404
David Benjamin3989c992020-10-09 14:12:06 -04007405TEST(SSLTest, BIO) {
7406 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007407 bssl::UniquePtr<SSL_CTX> server_ctx(
7408 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007409 ASSERT_TRUE(client_ctx);
7410 ASSERT_TRUE(server_ctx);
7411
David Benjamin3989c992020-10-09 14:12:06 -04007412 for (bool take_ownership : {true, false}) {
7413 // For simplicity, get the handshake out of the way first.
7414 bssl::UniquePtr<SSL> client, server;
7415 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7416 server_ctx.get()));
7417
7418 // Wrap |client| in an SSL BIO.
7419 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7420 ASSERT_TRUE(client_bio);
7421 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7422 if (take_ownership) {
7423 client.release();
7424 }
7425
7426 // Flushing the BIO should not crash.
7427 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7428
7429 // Exchange some data.
7430 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7431 uint8_t buf[5];
7432 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7433 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7434
7435 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7436 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7437 EXPECT_EQ(Bytes("world"), Bytes(buf));
7438
7439 // |BIO_should_read| should work.
7440 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7441 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7442
7443 // Writing data should eventually exceed the buffer size and fail, reporting
7444 // |BIO_should_write|.
7445 int ret;
7446 for (int i = 0; i < 1024; i++) {
7447 std::vector<uint8_t> buffer(1024);
7448 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7449 if (ret <= 0) {
7450 break;
7451 }
7452 }
7453 EXPECT_EQ(-1, ret);
7454 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7455 }
7456}
7457
David Benjamin12a3e7e2021-04-13 11:47:36 -04007458TEST(SSLTest, ALPNConfig) {
7459 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7460 ASSERT_TRUE(ctx);
7461 bssl::UniquePtr<X509> cert = GetTestCertificate();
7462 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7463 ASSERT_TRUE(cert);
7464 ASSERT_TRUE(key);
7465 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7466 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7467
7468 // Set up some machinery to check the configured ALPN against what is actually
7469 // sent over the wire. Note that the ALPN callback is only called when the
7470 // client offers ALPN.
7471 std::vector<uint8_t> observed_alpn;
7472 SSL_CTX_set_alpn_select_cb(
7473 ctx.get(),
7474 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7475 unsigned in_len, void *arg) -> int {
7476 std::vector<uint8_t> *observed_alpn_ptr =
7477 static_cast<std::vector<uint8_t> *>(arg);
7478 observed_alpn_ptr->assign(in, in + in_len);
7479 return SSL_TLSEXT_ERR_NOACK;
7480 },
7481 &observed_alpn);
7482 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7483 observed_alpn.clear();
7484 bssl::UniquePtr<SSL> client, server;
7485 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7486 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7487 };
7488
7489 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7490 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7491 0x03, 'b', 'a', 'r'};
7492 EXPECT_EQ(0,
7493 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7494 check_alpn_proto(kValidList);
7495
7496 // Invalid lists are rejected.
7497 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7498 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7499 sizeof(kInvalidList)));
7500
7501 // Empty lists are valid and are interpreted as disabling ALPN.
7502 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7503 check_alpn_proto({});
7504}
7505
David Benjamin2f3958a2021-04-16 11:55:23 -04007506// Test that the key usage checker can correctly handle issuerUID and
7507// subjectUID. See https://crbug.com/1199744.
7508TEST(SSLTest, KeyUsageWithUIDs) {
7509 static const char kGoodKeyUsage[] = R"(
7510-----BEGIN CERTIFICATE-----
7511MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7512AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7513aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7514CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7515ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
75164r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7517Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7518ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7519A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
752034EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
75214Z7qDhjIhiF4dM0uEDYRVA==
7522-----END CERTIFICATE-----
7523)";
7524 static const char kBadKeyUsage[] = R"(
7525-----BEGIN CERTIFICATE-----
7526MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7527AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7528aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7529CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7530ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
75314r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7532Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7533ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7534A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7535taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7536RHrQbWsFUakETXL9QMlegh5t
7537-----END CERTIFICATE-----
7538)";
7539
7540 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7541 ASSERT_TRUE(good);
7542 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7543 ASSERT_TRUE(bad);
7544
7545 // We check key usage when configuring EC certificates to distinguish ECDSA
7546 // and ECDH.
7547 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7548 ASSERT_TRUE(ctx);
7549 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7550 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7551}
7552
David Benjamin9b2cdb72021-04-01 23:21:53 -04007553// Test that |SSL_can_release_private_key| reports true as early as expected.
7554// The internal asserts in the library check we do not report true too early.
7555TEST(SSLTest, CanReleasePrivateKey) {
7556 bssl::UniquePtr<SSL_CTX> client_ctx =
7557 CreateContextWithTestCertificate(TLS_method());
7558 ASSERT_TRUE(client_ctx);
7559 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7560
7561 // Note this assumes the transport buffer is large enough to fit the client
7562 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7563 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7564 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7565 // Write the ClientHello.
7566 ASSERT_EQ(-1, SSL_do_handshake(client));
7567 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7568
7569 // Consume the ClientHello and write the server flight.
7570 ASSERT_EQ(-1, SSL_do_handshake(server));
7571 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7572
7573 EXPECT_TRUE(SSL_can_release_private_key(server));
7574 };
7575
7576 {
7577 SCOPED_TRACE("TLS 1.2 ECDHE");
7578 bssl::UniquePtr<SSL_CTX> server_ctx(
7579 CreateContextWithTestCertificate(TLS_method()));
7580 ASSERT_TRUE(server_ctx);
7581 ASSERT_TRUE(
7582 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7583 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7584 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7585 // Configure the server to request client certificates, so we can also test
7586 // the client half.
7587 SSL_CTX_set_custom_verify(
7588 server_ctx.get(), SSL_VERIFY_PEER,
7589 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7590 bssl::UniquePtr<SSL> client, server;
7591 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7592 server_ctx.get()));
7593 check_first_server_round_trip(client.get(), server.get());
7594
7595 // Consume the server flight and write the client response. The client still
7596 // has a Finished message to consume but can also release its key early.
7597 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7598 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7599 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7600
7601 // However, a client that has not disabled renegotiation can never release
7602 // the key.
7603 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7604 server_ctx.get()));
7605 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7606 check_first_server_round_trip(client.get(), server.get());
7607 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7608 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7609 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7610 }
7611
7612 {
7613 SCOPED_TRACE("TLS 1.2 resumption");
7614 bssl::UniquePtr<SSL_CTX> server_ctx(
7615 CreateContextWithTestCertificate(TLS_method()));
7616 ASSERT_TRUE(server_ctx);
7617 ASSERT_TRUE(
7618 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7619 bssl::UniquePtr<SSL_SESSION> session =
7620 CreateClientSession(client_ctx.get(), server_ctx.get());
7621 ASSERT_TRUE(session);
7622 bssl::UniquePtr<SSL> client, server;
7623 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7624 server_ctx.get()));
7625 SSL_set_session(client.get(), session.get());
7626 check_first_server_round_trip(client.get(), server.get());
7627 }
7628
7629 {
7630 SCOPED_TRACE("TLS 1.3 1-RTT");
7631 bssl::UniquePtr<SSL_CTX> server_ctx(
7632 CreateContextWithTestCertificate(TLS_method()));
7633 ASSERT_TRUE(server_ctx);
7634 ASSERT_TRUE(
7635 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7636 bssl::UniquePtr<SSL> client, server;
7637 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7638 server_ctx.get()));
7639 check_first_server_round_trip(client.get(), server.get());
7640 }
7641
7642 {
7643 SCOPED_TRACE("TLS 1.3 resumption");
7644 bssl::UniquePtr<SSL_CTX> server_ctx(
7645 CreateContextWithTestCertificate(TLS_method()));
7646 ASSERT_TRUE(server_ctx);
7647 ASSERT_TRUE(
7648 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7649 bssl::UniquePtr<SSL_SESSION> session =
7650 CreateClientSession(client_ctx.get(), server_ctx.get());
7651 ASSERT_TRUE(session);
7652 bssl::UniquePtr<SSL> client, server;
7653 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7654 server_ctx.get()));
7655 SSL_set_session(client.get(), session.get());
7656 check_first_server_round_trip(client.get(), server.get());
7657 }
7658}
7659
David Benjamine9c5d722021-06-09 17:43:16 -04007660// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7661// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7662// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7663// will be set to the ClientHelloInner's extensions, rather than
7664// ClientHelloOuter.
7665static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7666 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7667 struct AppData {
7668 std::vector<uint16_t> *out;
7669 bool decrypt_ech;
7670 bool callback_done = false;
7671 };
7672 AppData app_data;
7673 app_data.out = out;
7674 app_data.decrypt_ech = decrypt_ech;
7675
7676 bssl::UniquePtr<SSL_CTX> server_ctx =
7677 CreateContextWithTestCertificate(TLS_method());
7678 if (!server_ctx || //
7679 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7680 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7681 return false;
7682 }
7683
7684 // Configure the server to record the ClientHello extension order. We use a
7685 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7686 SSL_CTX_set_select_certificate_cb(
7687 server_ctx.get(),
7688 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7689 AppData *app_data_ptr = static_cast<AppData *>(
7690 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7691 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7692 SSL_ech_accepted(client_hello->ssl));
7693
7694 app_data_ptr->out->clear();
7695 CBS extensions;
7696 CBS_init(&extensions, client_hello->extensions,
7697 client_hello->extensions_len);
7698 while (CBS_len(&extensions)) {
7699 uint16_t type;
7700 CBS body;
7701 if (!CBS_get_u16(&extensions, &type) ||
7702 !CBS_get_u16_length_prefixed(&extensions, &body)) {
7703 return ssl_select_cert_error;
7704 }
7705 app_data_ptr->out->push_back(type);
7706 }
7707
7708 // Don't bother completing the handshake.
7709 app_data_ptr->callback_done = true;
7710 return ssl_select_cert_error;
7711 });
7712
7713 bssl::UniquePtr<SSL> client, server;
7714 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
7715 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
7716 return false;
7717 }
7718
7719 // Run the handshake far enough to process the ClientHello.
7720 SSL_do_handshake(client.get());
7721 SSL_do_handshake(server.get());
7722 return app_data.callback_done;
7723}
7724
7725// Test that, when extension permutation is enabled, the ClientHello extension
7726// order changes, both with and without ECH, and in both ClientHelloInner and
7727// ClientHelloOuter.
7728TEST(SSLTest, PermuteExtensions) {
7729 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
7730 ASSERT_TRUE(keys);
7731 for (bool offer_ech : {false, true}) {
7732 SCOPED_TRACE(offer_ech);
7733 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
7734 for (bool decrypt_ech : {false, true}) {
7735 SCOPED_TRACE(decrypt_ech);
7736 if (!offer_ech && decrypt_ech) {
7737 continue;
7738 }
7739
7740 // When extension permutation is disabled, the order should be consistent.
7741 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7742 ASSERT_TRUE(ctx);
7743 std::vector<uint16_t> order1, order2;
7744 ASSERT_TRUE(
7745 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7746 ASSERT_TRUE(
7747 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7748 EXPECT_EQ(order1, order2);
7749
7750 ctx.reset(SSL_CTX_new(TLS_method()));
7751 ASSERT_TRUE(ctx);
7752 SSL_CTX_set_permute_extensions(ctx.get(), 1);
7753
7754 // When extension permutation is enabled, each ClientHello should have a
7755 // different order.
7756 //
7757 // This test is inherently flaky, so we run it multiple times. We send at
7758 // least five extensions by default from TLS 1.3: supported_versions,
7759 // key_share, supported_groups, psk_key_exchange_modes, and
7760 // signature_algorithms. That means the probability of a false negative is
7761 // at most 1/120. Repeating the test 14 times lowers false negative rate
7762 // to under 2^-96.
7763 ASSERT_TRUE(
7764 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7765 EXPECT_GE(order1.size(), 5u);
7766 static const int kNumIterations = 14;
7767 bool passed = false;
7768 for (int i = 0; i < kNumIterations; i++) {
7769 ASSERT_TRUE(
7770 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7771 if (order1 != order2) {
7772 passed = true;
7773 break;
7774 }
7775 }
7776 EXPECT_TRUE(passed) << "Extensions were not permuted";
7777 }
7778 }
7779}
7780
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007781} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007782BSSL_NAMESPACE_END