blob: ceb52def0ca8e3dfb751856be8c4eccd1e06869b [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()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001952}
1953
David Benjamin83a49932021-05-20 15:57:09 -04001954// Test that |SSL_get_client_random| reports the correct value on both client
1955// and server in ECH. The client sends two different random values. When ECH is
1956// accepted, we should report the inner one.
1957TEST(SSLTest, ECHClientRandomsMatch) {
1958 bssl::UniquePtr<SSL_CTX> server_ctx =
1959 CreateContextWithTestCertificate(TLS_method());
1960 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
1961 ASSERT_TRUE(keys);
1962 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
1963
1964 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1965 ASSERT_TRUE(client_ctx);
1966 bssl::UniquePtr<SSL> client, server;
1967 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
1968 server_ctx.get()));
1969 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
1970 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
1971
1972 EXPECT_TRUE(SSL_ech_accepted(client.get()));
1973 EXPECT_TRUE(SSL_ech_accepted(server.get()));
1974
1975 // An ECH server will fairly naturally record the inner ClientHello random,
1976 // but an ECH client may forget to update the random once ClientHelloInner is
1977 // selected.
1978 uint8_t client_random1[SSL3_RANDOM_SIZE];
1979 uint8_t client_random2[SSL3_RANDOM_SIZE];
1980 ASSERT_EQ(sizeof(client_random1),
1981 SSL_get_client_random(client.get(), client_random1,
1982 sizeof(client_random1)));
1983 ASSERT_EQ(sizeof(client_random2),
1984 SSL_get_client_random(server.get(), client_random2,
1985 sizeof(client_random2)));
1986 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
1987}
1988
1989// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
1990// of the ClientHello and ECH extension, respectively, when a client created
1991// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
1992// maximum name length |max_name_len|.
1993static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
1994 size_t *out_ech_len, size_t max_name_len,
1995 const char *name) {
1996 bssl::ScopedEVP_HPKE_KEY key;
1997 uint8_t *ech_config;
1998 size_t ech_config_len;
1999 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
2000 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
2001 /*config_id=*/1, key.get(), "public.example",
2002 max_name_len)) {
2003 return false;
2004 }
2005 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2006
2007 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2008 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2009 ech_config_len, key.get())) {
2010 return false;
2011 }
2012
2013 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
2014 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
2015 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
2016 return false;
2017 }
2018 SSL_set_connect_state(ssl.get());
2019
2020 std::vector<uint8_t> client_hello;
2021 SSL_CLIENT_HELLO parsed;
2022 const uint8_t *unused;
2023 if (!GetClientHello(ssl.get(), &client_hello) ||
2024 !ssl_client_hello_init(
2025 ssl.get(), &parsed,
2026 // Skip record and handshake headers. This assumes the ClientHello
2027 // fits in one record.
2028 MakeConstSpan(client_hello)
2029 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
2030 !SSL_early_callback_ctx_extension_get(
2031 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2032 return false;
2033 }
2034 *out_client_hello_len = client_hello.size();
2035 return true;
2036}
2037
2038TEST(SSLTest, ECHPadding) {
2039 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2040 ASSERT_TRUE(ctx);
2041
2042 // Sample lengths with max_name_len = 128 as baseline.
2043 size_t client_hello_len_baseline, ech_len_baseline;
2044 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2045 &ech_len_baseline, 128, "example.com"));
2046
2047 // Check that all name lengths under the server's maximum look the same.
2048 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2049 SCOPED_TRACE(name_len);
2050 size_t client_hello_len, ech_len;
2051 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2052 std::string(name_len, 'a').c_str()));
2053 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2054 EXPECT_EQ(ech_len, ech_len_baseline);
2055 }
2056
2057 // When sending no SNI, we must still pad as if we are sending one.
2058 size_t client_hello_len, ech_len;
2059 ASSERT_TRUE(
2060 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2061 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2062 EXPECT_EQ(ech_len, ech_len_baseline);
2063
2064 size_t client_hello_len_129, ech_len_129;
2065 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_129, &ech_len_129, 128,
2066 std::string(129, 'a').c_str()));
2067 // The padding calculation should not pad beyond the maximum.
2068 EXPECT_GT(ech_len_129, ech_len_baseline);
2069
2070 // If the SNI exceeds the maximum name length, we apply some generic padding,
2071 // so close name lengths still match.
2072 for (size_t name_len : {129, 130, 131, 132}) {
2073 SCOPED_TRACE(name_len);
2074 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2075 std::string(name_len, 'a').c_str()));
2076 EXPECT_EQ(client_hello_len, client_hello_len_129);
2077 EXPECT_EQ(ech_len, ech_len_129);
2078 }
2079}
2080
2081#if defined(OPENSSL_THREADS)
2082// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2083// in use on other threads. This test is intended to be run with TSan.
2084TEST(SSLTest, ECHThreads) {
2085 // Generate a pair of ECHConfigs.
2086 bssl::ScopedEVP_HPKE_KEY key1;
2087 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2088 uint8_t *ech_config1;
2089 size_t ech_config1_len;
2090 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2091 /*config_id=*/1, key1.get(),
2092 "public.example", 16));
2093 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2094 bssl::ScopedEVP_HPKE_KEY key2;
2095 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2096 uint8_t *ech_config2;
2097 size_t ech_config2_len;
2098 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2099 /*config_id=*/2, key2.get(),
2100 "public.example", 16));
2101 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2102
2103 // |keys1| contains the first config. |keys12| contains both.
2104 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2105 ASSERT_TRUE(keys1);
2106 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2107 ech_config1_len, key1.get()));
2108 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2109 ASSERT_TRUE(keys12);
2110 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2111 ech_config2_len, key2.get()));
2112 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2113 ech_config1_len, key1.get()));
2114
2115 bssl::UniquePtr<SSL_CTX> server_ctx =
2116 CreateContextWithTestCertificate(TLS_method());
2117 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2118
2119 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2120 ASSERT_TRUE(client_ctx);
2121 bssl::UniquePtr<SSL> client, server;
2122 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2123 server_ctx.get()));
2124 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2125
2126 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2127 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2128 // the same whichever the server uses.
2129 std::vector<std::thread> threads;
2130 threads.emplace_back([&] {
2131 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2132 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2133 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2134 });
2135 threads.emplace_back([&] {
2136 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2137 });
2138 for (auto &thread : threads) {
2139 thread.join();
2140 }
2141}
2142#endif // OPENSSL_THREADS
2143
David Benjaminc79ae7a2017-08-29 16:09:44 -04002144static void AppendSession(SSL_SESSION *session, void *arg) {
2145 std::vector<SSL_SESSION*> *out =
2146 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2147 out->push_back(session);
2148}
2149
2150// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2151// order.
2152static bool CacheEquals(SSL_CTX *ctx,
2153 const std::vector<SSL_SESSION*> &expected) {
2154 // Check the linked list.
2155 SSL_SESSION *ptr = ctx->session_cache_head;
2156 for (SSL_SESSION *session : expected) {
2157 if (ptr != session) {
2158 return false;
2159 }
2160 // TODO(davidben): This is an absurd way to denote the end of the list.
2161 if (ptr->next ==
2162 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2163 ptr = nullptr;
2164 } else {
2165 ptr = ptr->next;
2166 }
2167 }
2168 if (ptr != nullptr) {
2169 return false;
2170 }
2171
2172 // Check the hash table.
2173 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002174 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002175 expected_copy = expected;
2176
2177 std::sort(actual.begin(), actual.end());
2178 std::sort(expected_copy.begin(), expected_copy.end());
2179
2180 return actual == expected_copy;
2181}
2182
2183static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2184 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2185 if (!ssl_ctx) {
2186 return nullptr;
2187 }
2188 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2189 if (!ret) {
2190 return nullptr;
2191 }
2192
David Benjaminaaef8332018-06-29 16:45:49 -04002193 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2194 OPENSSL_memcpy(id, &number, sizeof(number));
2195 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2196 return nullptr;
2197 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002198 return ret;
2199}
2200
2201// Test that the internal session cache behaves as expected.
2202TEST(SSLTest, InternalSessionCache) {
2203 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2204 ASSERT_TRUE(ctx);
2205
2206 // Prepare 10 test sessions.
2207 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2208 for (int i = 0; i < 10; i++) {
2209 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2210 ASSERT_TRUE(session);
2211 sessions.push_back(std::move(session));
2212 }
2213
2214 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2215
2216 // Insert all the test sessions.
2217 for (const auto &session : sessions) {
2218 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2219 }
2220
2221 // Only the last five should be in the list.
2222 ASSERT_TRUE(CacheEquals(
2223 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2224 sessions[6].get(), sessions[5].get()}));
2225
2226 // Inserting an element already in the cache should fail and leave the cache
2227 // unchanged.
2228 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2229 ASSERT_TRUE(CacheEquals(
2230 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2231 sessions[6].get(), sessions[5].get()}));
2232
2233 // Although collisions should be impossible (256-bit session IDs), the cache
2234 // must handle them gracefully.
2235 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2236 ASSERT_TRUE(collision);
2237 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2238 ASSERT_TRUE(CacheEquals(
2239 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2240 sessions[6].get(), sessions[5].get()}));
2241
2242 // Removing sessions behaves correctly.
2243 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2244 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2245 sessions[8].get(), sessions[5].get()}));
2246
2247 // Removing sessions requires an exact match.
2248 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2249 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2250
2251 // The cache remains unchanged.
2252 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2253 sessions[8].get(), sessions[5].get()}));
2254}
2255
2256static uint16_t EpochFromSequence(uint64_t seq) {
2257 return static_cast<uint16_t>(seq >> 48);
2258}
2259
David Benjamin71dfad42017-07-16 17:27:39 -04002260static const uint8_t kTestName[] = {
2261 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2262 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2263 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2264 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2265 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2266 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2267};
2268
David Benjaminc11ea9422017-08-29 16:33:21 -04002269// SSLVersionTest executes its test cases under all available protocol versions.
2270// Test cases call |Connect| to create a connection using context objects with
2271// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002272class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2273 protected:
2274 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2275
2276 void SetUp() { ResetContexts(); }
2277
2278 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2279 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2280 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2281 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2282 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2283 return nullptr;
2284 }
2285 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002286 }
David Benjamin686bb192016-05-10 15:15:41 -04002287
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002288 void ResetContexts() {
2289 ASSERT_TRUE(cert_);
2290 ASSERT_TRUE(key_);
2291 client_ctx_ = CreateContext();
2292 ASSERT_TRUE(client_ctx_);
2293 server_ctx_ = CreateContext();
2294 ASSERT_TRUE(server_ctx_);
2295 // Set up a server cert. Client certs can be set up explicitly.
2296 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002297 }
David Benjamin686bb192016-05-10 15:15:41 -04002298
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002299 bool UseCertAndKey(SSL_CTX *ctx) const {
2300 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2301 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002302 }
David Benjamin686bb192016-05-10 15:15:41 -04002303
David Benjamina8614602017-09-06 15:40:19 -04002304 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002305 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002306 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002307 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002308 }
2309
2310 uint16_t version() const { return GetParam().version; }
2311
2312 bool is_dtls() const {
2313 return GetParam().ssl_method == VersionParam::is_dtls;
2314 }
2315
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002316 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002317 bssl::UniquePtr<SSL> client_, server_;
2318 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2319 bssl::UniquePtr<X509> cert_;
2320 bssl::UniquePtr<EVP_PKEY> key_;
2321};
2322
David Benjaminbe7006a2019-04-09 18:05:02 -05002323INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2324 testing::ValuesIn(kAllVersions),
2325 [](const testing::TestParamInfo<VersionParam> &i) {
2326 return i.param.name;
2327 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002328
2329TEST_P(SSLVersionTest, SequenceNumber) {
2330 ASSERT_TRUE(Connect());
2331
David Benjamin0fef3052016-11-18 15:11:10 +09002332 // Drain any post-handshake messages to ensure there are no unread records
2333 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002334 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002335
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002336 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2337 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2338 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2339 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002340
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002341 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002342 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002343 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2344 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2345 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2346 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002347
2348 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002349 EXPECT_GT(client_write_seq, server_read_seq);
2350 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002351 } else {
2352 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002353 EXPECT_EQ(client_write_seq, server_read_seq);
2354 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002355 }
2356
2357 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002358 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002359 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2360 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002361
2362 // The client write and server read sequence numbers should have
2363 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002364 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2365 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002366}
2367
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002368TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002369 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002370 if (is_dtls()) {
2371 return;
David Benjamin686bb192016-05-10 15:15:41 -04002372 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002373 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002374
David Benjamin9734e442021-06-15 13:58:12 -04002375 // Shut down half the connection. |SSL_shutdown| will return 0 to signal only
David Benjamin686bb192016-05-10 15:15:41 -04002376 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002377 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002378
2379 // Reading from the server should consume the EOF.
2380 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002381 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2382 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002383
2384 // However, the server may continue to write data and then shut down the
2385 // connection.
2386 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002387 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2388 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2389 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002390
2391 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002392 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2393 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002394}
David Benjamin68f37b72016-11-18 15:14:42 +09002395
David Benjamin9734e442021-06-15 13:58:12 -04002396// Test that, after calling |SSL_shutdown|, |SSL_write| fails.
2397TEST_P(SSLVersionTest, WriteAfterShutdown) {
2398 ASSERT_TRUE(Connect());
2399
2400 for (SSL *ssl : {client_.get(), server_.get()}) {
2401 SCOPED_TRACE(SSL_is_server(ssl) ? "server" : "client");
2402
2403 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2404 ASSERT_TRUE(mem);
2405 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2406
2407 // Shut down half the connection. |SSL_shutdown| will return 0 to signal
2408 // only one side has shut down.
2409 ASSERT_EQ(SSL_shutdown(ssl), 0);
2410
2411 // |ssl| should have written an alert to the transport.
2412 const uint8_t *unused;
2413 size_t len;
2414 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2415 EXPECT_NE(0u, len);
2416 EXPECT_TRUE(BIO_reset(mem.get()));
2417
2418 // Writing should fail.
2419 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2420
2421 // Nothing should be written to the transport.
2422 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2423 EXPECT_EQ(0u, len);
2424 }
2425}
2426
2427// Test that, after sending a fatal alert in a failed |SSL_read|, |SSL_write|
2428// fails.
2429TEST_P(SSLVersionTest, WriteAfterReadSentFatalAlert) {
2430 // Decryption failures are not fatal in DTLS.
2431 if (is_dtls()) {
2432 return;
2433 }
2434
2435 ASSERT_TRUE(Connect());
2436
2437 // Save the write |BIO|s as the test will overwrite them.
2438 bssl::UniquePtr<BIO> client_wbio = bssl::UpRef(SSL_get_wbio(client_.get()));
2439 bssl::UniquePtr<BIO> server_wbio = bssl::UpRef(SSL_get_wbio(server_.get()));
2440
2441 for (bool test_server : {false, true}) {
2442 SCOPED_TRACE(test_server ? "server" : "client");
2443 SSL *ssl = test_server ? server_.get() : client_.get();
2444 BIO *other_wbio = test_server ? client_wbio.get() : server_wbio.get();
2445
2446 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2447 ASSERT_TRUE(mem);
2448 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2449
2450 // Read an invalid record from the peer.
2451 static const uint8_t kInvalidRecord[] = "invalid record";
2452 EXPECT_EQ(int{sizeof(kInvalidRecord)},
2453 BIO_write(other_wbio, kInvalidRecord, sizeof(kInvalidRecord)));
2454 char buf[256];
2455 EXPECT_EQ(-1, SSL_read(ssl, buf, sizeof(buf)));
2456
2457 // |ssl| should have written an alert to the transport.
2458 const uint8_t *unused;
2459 size_t len;
2460 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2461 EXPECT_NE(0u, len);
2462 EXPECT_TRUE(BIO_reset(mem.get()));
2463
2464 // Writing should fail.
2465 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2466
2467 // Nothing should be written to the transport.
2468 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2469 EXPECT_EQ(0u, len);
2470 }
2471}
2472
2473// Test that, after sending a fatal alert from the handshake, |SSL_write| fails.
2474TEST_P(SSLVersionTest, WriteAfterHandshakeSentFatalAlert) {
2475 for (bool test_server : {false, true}) {
2476 SCOPED_TRACE(test_server ? "server" : "client");
2477
2478 bssl::UniquePtr<SSL> ssl(
2479 SSL_new(test_server ? server_ctx_.get() : client_ctx_.get()));
2480 ASSERT_TRUE(ssl);
2481 if (test_server) {
2482 SSL_set_accept_state(ssl.get());
2483 } else {
2484 SSL_set_connect_state(ssl.get());
2485 }
2486
2487 std::vector<uint8_t> invalid;
2488 if (is_dtls()) {
2489 // In DTLS, invalid records are discarded. To cause the handshake to fail,
2490 // use a valid handshake record with invalid contents.
2491 invalid.push_back(SSL3_RT_HANDSHAKE);
2492 invalid.push_back(DTLS1_VERSION >> 8);
2493 invalid.push_back(DTLS1_VERSION & 0xff);
2494 // epoch and sequence_number
2495 for (int i = 0; i < 8; i++) {
2496 invalid.push_back(0);
2497 }
2498 // A one-byte fragment is invalid.
2499 invalid.push_back(0);
2500 invalid.push_back(1);
2501 // Arbitrary contents.
2502 invalid.push_back(0);
2503 } else {
2504 invalid = {'i', 'n', 'v', 'a', 'l', 'i', 'd'};
2505 }
2506 bssl::UniquePtr<BIO> rbio(
2507 BIO_new_mem_buf(invalid.data(), invalid.size()));
2508 ASSERT_TRUE(rbio);
2509 SSL_set0_rbio(ssl.get(), rbio.release());
2510
2511 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2512 ASSERT_TRUE(mem);
2513 SSL_set0_wbio(ssl.get(), bssl::UpRef(mem).release());
2514
2515 // The handshake should fail.
2516 EXPECT_EQ(-1, SSL_do_handshake(ssl.get()));
2517 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2518 uint32_t err = ERR_get_error();
2519
2520 // |ssl| should have written an alert (and, in the client's case, a
2521 // ClientHello) to the transport.
2522 const uint8_t *unused;
2523 size_t len;
2524 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2525 EXPECT_NE(0u, len);
2526 EXPECT_TRUE(BIO_reset(mem.get()));
2527
2528 // Writing should fail, with the same error as the handshake.
2529 EXPECT_EQ(-1, SSL_write(ssl.get(), "a", 1));
2530 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2531 EXPECT_EQ(err, ERR_get_error());
2532
2533 // Nothing should be written to the transport.
2534 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2535 EXPECT_EQ(0u, len);
2536 }
2537}
2538
2539// Test that, after seeing TLS 1.2 in response to early data, |SSL_write|
2540// continues to report |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. See
2541// https://crbug.com/1078515.
2542TEST(SSLTest, WriteAfterWrongVersionOnEarlyData) {
2543 // Set up some 0-RTT-enabled contexts.
2544 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2545 bssl::UniquePtr<SSL_CTX> server_ctx =
2546 CreateContextWithTestCertificate(TLS_method());
2547 ASSERT_TRUE(client_ctx);
2548 ASSERT_TRUE(server_ctx);
2549 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
2550 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
2551 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2552 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2553
2554 // Get an early-data-capable session.
2555 bssl::UniquePtr<SSL_SESSION> session =
2556 CreateClientSession(client_ctx.get(), server_ctx.get());
2557 ASSERT_TRUE(session);
2558 EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
2559
2560 // Offer the session to the server, but now the server speaks TLS 1.2.
2561 bssl::UniquePtr<SSL> client, server;
2562 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2563 server_ctx.get()));
2564 SSL_set_session(client.get(), session.get());
2565 EXPECT_TRUE(SSL_set_max_proto_version(server.get(), TLS1_2_VERSION));
2566
2567 // The client handshake initially succeeds in the early data state.
2568 EXPECT_EQ(1, SSL_do_handshake(client.get()));
2569 EXPECT_TRUE(SSL_in_early_data(client.get()));
2570
2571 // The server processes the ClientHello and negotiates TLS 1.2.
2572 EXPECT_EQ(-1, SSL_do_handshake(server.get()));
2573 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server.get(), -1));
2574 EXPECT_EQ(TLS1_2_VERSION, SSL_version(server.get()));
2575
2576 // Capture the client's output.
2577 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2578 ASSERT_TRUE(mem);
2579 SSL_set0_wbio(client.get(), bssl::UpRef(mem).release());
2580
2581 // The client processes the ServerHello and fails.
2582 EXPECT_EQ(-1, SSL_do_handshake(client.get()));
2583 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2584 uint32_t err = ERR_get_error();
2585 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2586 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2587
2588 // The client should have written an alert to the transport.
2589 const uint8_t *unused;
2590 size_t len;
2591 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2592 EXPECT_NE(0u, len);
2593 EXPECT_TRUE(BIO_reset(mem.get()));
2594
2595 // Writing should fail, with the same error as the handshake.
2596 EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
2597 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2598 err = ERR_get_error();
2599 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2600 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2601
2602 // Nothing should be written to the transport.
2603 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2604 EXPECT_EQ(0u, len);
2605}
2606
David Benjaminf0d8e222017-02-04 10:58:26 -05002607TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002608 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002609 bssl::UniquePtr<SSL_CTX> server_ctx =
2610 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002611 ASSERT_TRUE(client_ctx);
2612 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002613
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002614 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002615 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002616 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002617
2618 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002619 bssl::UniquePtr<SSL_SESSION> session1 =
2620 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002621 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002622
David Benjamina3a71e92018-06-29 13:24:45 -04002623 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002624
Steven Valdez87eab492016-06-27 16:34:59 -04002625 uint8_t *s0_bytes, *s1_bytes;
2626 size_t s0_len, s1_len;
2627
David Benjaminf0d8e222017-02-04 10:58:26 -05002628 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002629 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002630
David Benjaminf0d8e222017-02-04 10:58:26 -05002631 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002632 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002633
David Benjamin7d7554b2017-02-04 11:48:59 -05002634 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002635}
David Benjamin686bb192016-05-10 15:15:41 -04002636
David Benjaminf0d8e222017-02-04 10:58:26 -05002637static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002638 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002639 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2640 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002641
2642 // The wrapper BIOs are always equal when fds are equal, even if set
2643 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002644 if (rfd == wfd) {
2645 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002646 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002647}
2648
David Benjaminf0d8e222017-02-04 10:58:26 -05002649TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002650 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002651 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002652
2653 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002654 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002655 ASSERT_TRUE(ssl);
2656 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2657 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2658 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002659
2660 // Test setting the same FD.
2661 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002662 ASSERT_TRUE(ssl);
2663 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2664 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002665
2666 // Test setting the same FD one side at a time.
2667 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002668 ASSERT_TRUE(ssl);
2669 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2670 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2671 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002672
2673 // Test setting the same FD in the other order.
2674 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002675 ASSERT_TRUE(ssl);
2676 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2677 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2678 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002679
David Benjamin5c0fb882016-06-14 14:03:51 -04002680 // Test changing the read FD partway through.
2681 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002682 ASSERT_TRUE(ssl);
2683 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2684 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2685 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002686
2687 // Test changing the write FD partway through.
2688 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002689 ASSERT_TRUE(ssl);
2690 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2691 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2692 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002693
2694 // Test a no-op change to the read FD partway through.
2695 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002696 ASSERT_TRUE(ssl);
2697 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2698 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2699 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002700
2701 // Test a no-op change to the write FD partway through.
2702 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002703 ASSERT_TRUE(ssl);
2704 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2705 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2706 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002707
2708 // ASan builds will implicitly test that the internal |BIO| reference-counting
2709 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002710}
2711
David Benjaminf0d8e222017-02-04 10:58:26 -05002712TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002713 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002714 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002715
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002716 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2717 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002718 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002719 ASSERT_TRUE(ssl);
2720 ASSERT_TRUE(bio1);
2721 ASSERT_TRUE(bio2);
2722 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002723
2724 // SSL_set_bio takes one reference when the parameters are the same.
2725 BIO_up_ref(bio1.get());
2726 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2727
2728 // Repeating the call does nothing.
2729 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2730
2731 // It takes one reference each when the parameters are different.
2732 BIO_up_ref(bio2.get());
2733 BIO_up_ref(bio3.get());
2734 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2735
2736 // Repeating the call does nothing.
2737 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2738
2739 // It takes one reference when changing only wbio.
2740 BIO_up_ref(bio1.get());
2741 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2742
2743 // It takes one reference when changing only rbio and the two are different.
2744 BIO_up_ref(bio3.get());
2745 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2746
2747 // If setting wbio to rbio, it takes no additional references.
2748 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2749
2750 // From there, wbio may be switched to something else.
2751 BIO_up_ref(bio1.get());
2752 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2753
2754 // If setting rbio to wbio, it takes no additional references.
2755 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2756
2757 // From there, rbio may be switched to something else, but, for historical
2758 // reasons, it takes a reference to both parameters.
2759 BIO_up_ref(bio1.get());
2760 BIO_up_ref(bio2.get());
2761 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2762
2763 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2764 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002765}
2766
David Benjamin25490f22016-07-14 00:22:54 -04002767static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2768
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002769TEST_P(SSLVersionTest, GetPeerCertificate) {
2770 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002771
David Benjamin0fef3052016-11-18 15:11:10 +09002772 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002773 SSL_CTX_set_verify(client_ctx_.get(),
2774 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2775 nullptr);
2776 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2777 SSL_CTX_set_verify(server_ctx_.get(),
2778 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2779 nullptr);
2780 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002781
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002782 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002783
David Benjamin0fef3052016-11-18 15:11:10 +09002784 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002785 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2786 ASSERT_TRUE(peer);
2787 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002788
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 peer.reset(SSL_get_peer_certificate(client_.get()));
2790 ASSERT_TRUE(peer);
2791 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002792
David Benjamine664a532017-07-20 20:19:36 -04002793 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002794 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002795 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2796 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2797 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002798
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2800 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2801 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002802}
2803
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804TEST_P(SSLVersionTest, NoPeerCertificate) {
2805 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2806 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2807 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002808
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002809 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811 // Server should not see a peer certificate.
2812 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2813 ASSERT_FALSE(peer);
2814 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002815}
2816
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002817TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002818 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002819 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2820 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002821 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002822
2823 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2824 SHA256(cert_der, cert_der_len, cert_sha256);
2825
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002826 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2827
David Benjamin0fef3052016-11-18 15:11:10 +09002828 // Configure both client and server to accept any certificate, but the
2829 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002830 SSL_CTX_set_verify(client_ctx_.get(),
2831 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2832 nullptr);
2833 SSL_CTX_set_verify(server_ctx_.get(),
2834 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2835 nullptr);
2836 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2837 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2838 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002839
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002840 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002841
David Benjamin0fef3052016-11-18 15:11:10 +09002842 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002843 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2844 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002845
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002846 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002847 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002848
David Benjamin02de7bd2018-05-08 18:13:54 -04002849 const uint8_t *peer_sha256;
2850 size_t peer_sha256_len;
2851 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2852 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002853}
2854
David Benjamin737d2df2017-09-25 15:05:19 -04002855// Tests that our ClientHellos do not change unexpectedly. These are purely
2856// change detection tests. If they fail as part of an intentional ClientHello
2857// change, update the test vector.
2858TEST(SSLTest, ClientHello) {
2859 struct {
2860 uint16_t max_version;
2861 std::vector<uint8_t> expected;
2862 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002863 {TLS1_VERSION,
2864 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2868 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002869 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2870 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2871 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002872 {TLS1_1_VERSION,
2873 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2874 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2877 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002878 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2879 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2880 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002881 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002882 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002886 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002887 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002888 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2889 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2890 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2891 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2892 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2893 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002894 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2895 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002896 };
David Benjamin737d2df2017-09-25 15:05:19 -04002897
2898 for (const auto &t : kTests) {
2899 SCOPED_TRACE(t.max_version);
2900
2901 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2902 ASSERT_TRUE(ctx);
2903 // Our default cipher list varies by CPU capabilities, so manually place the
2904 // ChaCha20 ciphers in front.
2905 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002906 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2907 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2908
2909 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2910 ASSERT_TRUE(ssl);
2911 std::vector<uint8_t> client_hello;
2912 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2913
2914 // Zero the client_random.
2915 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2916 1 + 3 + // handshake message header
2917 2; // client_version
2918 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2919 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2920
2921 if (client_hello != t.expected) {
2922 ADD_FAILURE() << "ClientHellos did not match.";
2923 // Print the value manually so it is easier to update the test vector.
2924 for (size_t i = 0; i < client_hello.size(); i += 12) {
2925 printf(" %c", i == 0 ? '{' : ' ');
2926 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2927 if (j > i) {
2928 printf(" ");
2929 }
2930 printf("0x%02x", client_hello[j]);
2931 if (j < client_hello.size() - 1) {
2932 printf(",");
2933 }
2934 }
2935 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002936 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002937 }
2938 printf("\n");
2939 }
2940 }
David Benjaminafc64de2016-07-19 17:12:41 +02002941 }
David Benjaminafc64de2016-07-19 17:12:41 +02002942}
2943
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002944static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2945 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002946 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002947 ClientConfig config;
2948 config.session = session;
2949 EXPECT_TRUE(
2950 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002951
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002952 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002953
2954 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002955 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002956}
2957
David Benjamin3c51d9b2016-11-01 17:50:42 -04002958static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2959 SSL_CTX *server_ctx,
2960 SSL_SESSION *session) {
2961 g_last_session = nullptr;
2962 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2963
2964 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002965 ClientConfig config;
2966 config.session = session;
2967 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002968 config) ||
2969 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002970 fprintf(stderr, "Failed to connect client and server.\n");
2971 return nullptr;
2972 }
2973
2974 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2975 fprintf(stderr, "Client and server were inconsistent.\n");
2976 return nullptr;
2977 }
2978
2979 if (!SSL_session_reused(client.get())) {
2980 fprintf(stderr, "Session was not reused.\n");
2981 return nullptr;
2982 }
2983
David Benjamin3c51d9b2016-11-01 17:50:42 -04002984 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2985
2986 if (!g_last_session) {
2987 fprintf(stderr, "Client did not receive a renewed session.\n");
2988 return nullptr;
2989 }
2990 return std::move(g_last_session);
2991}
2992
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002993static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002994 bool changed) {
2995 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002996 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002997 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2998 if (changed) {
2999 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3000 } else {
3001 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003002 }
3003 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003004}
3005
David Benjamina933c382016-10-28 00:10:03 -04003006static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
3007 static const uint8_t kContext[] = {3};
3008
3009 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
3010 return SSL_TLSEXT_ERR_ALERT_FATAL;
3011 }
3012
3013 return SSL_TLSEXT_ERR_OK;
3014}
3015
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003016TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04003017 static const uint8_t kContext1[] = {1};
3018 static const uint8_t kContext2[] = {2};
3019
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003020 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3021 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04003022
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003023 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3024 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04003025
David Benjamin0fef3052016-11-18 15:11:10 +09003026 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003027 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3028 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04003029
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003030 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3031 session.get(),
3032 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003033
David Benjamin0fef3052016-11-18 15:11:10 +09003034 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003035 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
3036 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04003037
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003038 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3039 session.get(),
3040 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003041
David Benjamin0fef3052016-11-18 15:11:10 +09003042 // Change the session ID context back and install an SNI callback to switch
3043 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003044 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3045 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04003046
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003047 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003048 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04003049
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003050 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3051 session.get(),
3052 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003053
David Benjamin0fef3052016-11-18 15:11:10 +09003054 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003055 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003056 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003057 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003058 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3059 static const uint8_t kContext[] = {3};
3060
3061 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
3062 sizeof(kContext))) {
3063 return ssl_select_cert_error;
3064 }
3065
3066 return ssl_select_cert_success;
3067 });
David Benjamina933c382016-10-28 00:10:03 -04003068
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003069 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3070 session.get(),
3071 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003072}
3073
David Benjamin721e8b72016-08-03 13:13:17 -04003074static timeval g_current_time;
3075
3076static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
3077 *out_clock = g_current_time;
3078}
3079
David Benjamin17b30832017-01-28 14:00:32 -05003080static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
3081 out_clock->tv_sec = 1000;
3082 out_clock->tv_usec = 0;
3083}
3084
David Benjamin3c51d9b2016-11-01 17:50:42 -04003085static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
3086 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
3087 int encrypt) {
3088 static const uint8_t kZeros[16] = {0};
3089
3090 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05003091 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04003092 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05003093 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003094 return 0;
3095 }
3096
3097 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
3098 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
3099 return -1;
3100 }
3101
3102 // Returning two from the callback in decrypt mode renews the
3103 // session in TLS 1.2 and below.
3104 return encrypt ? 1 : 2;
3105}
3106
David Benjamin123db572016-11-03 16:59:25 -04003107static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04003108 const uint8_t *ticket;
3109 size_t ticket_len;
3110 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
3111 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04003112 return false;
3113 }
3114
David Benjaminaaef8332018-06-29 16:45:49 -04003115 const uint8_t *ciphertext = ticket + 16 + 16;
3116 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04003117 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
3118
David Benjamin9b63f292016-11-15 00:44:05 -05003119#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3120 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05003121 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05003122#else
3123 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04003124 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04003125 bssl::ScopedEVP_CIPHER_CTX ctx;
3126 int len1, len2;
3127 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
3128 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
3129 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
3130 return false;
3131 }
3132
3133 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05003134#endif
David Benjamin123db572016-11-03 16:59:25 -04003135
Adam Langley46db7af2017-02-01 15:49:37 -08003136 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
3137 if (!ssl_ctx) {
3138 return false;
3139 }
David Benjamin123db572016-11-03 16:59:25 -04003140 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08003141 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04003142 if (!server_session) {
3143 return false;
3144 }
3145
David Benjaminaaef8332018-06-29 16:45:49 -04003146 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04003147 return true;
3148}
3149
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003150TEST_P(SSLVersionTest, SessionTimeout) {
3151 for (bool server_test : {false, true}) {
3152 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04003153
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003154 ResetContexts();
3155 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3156 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3157
David Benjamin17b30832017-01-28 14:00:32 -05003158 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09003159 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04003160
David Benjamin17b30832017-01-28 14:00:32 -05003161 // We are willing to use a longer lifetime for TLS 1.3 sessions as
3162 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003163 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05003164 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
3165 : SSL_DEFAULT_SESSION_TIMEOUT;
3166
David Benjamin17b30832017-01-28 14:00:32 -05003167 // Both client and server must enforce session timeouts. We configure the
3168 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09003169 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003170 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3171 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003172 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003173 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
3174 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003175 }
3176
3177 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003178 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003179
3180 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003181 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3182 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09003183
3184 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05003185 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09003186
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003187 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3188 session.get(),
3189 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003190
3191 // Advance the clock one more second.
3192 g_current_time.tv_sec++;
3193
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003194 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3195 session.get(),
3196 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003197
3198 // Rewind the clock to before the session was minted.
3199 g_current_time.tv_sec = kStartTime - 1;
3200
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003201 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3202 session.get(),
3203 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003204
David Benjamin0fef3052016-11-18 15:11:10 +09003205 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05003206 time_t new_start_time = kStartTime + timeout - 10;
3207 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003208 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
3209 client_ctx_.get(), server_ctx_.get(), session.get());
3210 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09003211
3212 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003213 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003214
3215 // Check the sessions have timestamps measured from issuance.
3216 long session_time = 0;
3217 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003218 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003219 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003220 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003221 }
David Benjamin721e8b72016-08-03 13:13:17 -04003222
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003223 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003224
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003225 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003226 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3227 // lifetime TLS 1.3.
3228 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003229 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3230 new_session.get(),
3231 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003232
David Benjamin17b30832017-01-28 14:00:32 -05003233 // The new session expires after the new timeout.
3234 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003235 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3236 new_session.get(),
3237 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003238
3239 // Renew the session until it begins just past the auth timeout.
3240 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3241 while (new_start_time < auth_end_time - 1000) {
3242 // Get as close as possible to target start time.
3243 new_start_time =
3244 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3245 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003246 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003247 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003248 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003249 }
3250
3251 // Now the session's lifetime is bound by the auth timeout.
3252 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003253 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3254 new_session.get(),
3255 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003256
3257 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003258 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3259 new_session.get(),
3260 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003261 } else {
3262 // The new session is usable just before the old expiration.
3263 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003264 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3265 new_session.get(),
3266 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003267
3268 // Renewal does not extend the lifetime, so it is not usable beyond the
3269 // old expiration.
3270 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003271 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3272 new_session.get(),
3273 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003274 }
David Benjamin721e8b72016-08-03 13:13:17 -04003275 }
David Benjamin721e8b72016-08-03 13:13:17 -04003276}
3277
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003278TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003279 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3280 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003281 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003282 kTicketKeyLen));
3283 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3284}
3285
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003286TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003287 static const time_t kStartTime = 1001;
3288 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003289
David Benjaminc11ea9422017-08-29 16:33:21 -04003290 // We use session reuse as a proxy for ticket decryption success, hence
3291 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003292 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3293 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003294 std::numeric_limits<uint32_t>::max());
3295
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003296 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3297 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003298
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003299 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3300 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003301
David Benjamin1f0d54b2018-08-09 16:19:13 -05003302 // Initialize ticket_key with the current key and check that it was
3303 // initialized to something, not all zeros.
3304 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003305 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3306 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003307
David Benjaminc11ea9422017-08-29 16:33:21 -04003308 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003309 bssl::UniquePtr<SSL> client, server;
3310 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003311 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003312 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003313 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003314 session.get(), true /* reused */));
3315
David Benjaminc11ea9422017-08-29 16:33:21 -04003316 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003317 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003318 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003319 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003320 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003321 false /* NOT changed */));
3322
David Benjaminc11ea9422017-08-29 16:33:21 -04003323 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003324 g_current_time.tv_sec += 1;
3325 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003326 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3327 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3328 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003329
David Benjaminc11ea9422017-08-29 16:33:21 -04003330 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003331 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003332 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003333 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003334 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003335 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003336 false /* NOT changed */));
3337
David Benjaminc11ea9422017-08-29 16:33:21 -04003338 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003339 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003340 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003341 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003342 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3343 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003344
David Benjaminc11ea9422017-08-29 16:33:21 -04003345 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003346 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003347 new_session.get(), true /* reused */));
3348}
3349
David Benjamin0fc37ef2016-08-17 15:29:46 -04003350static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003351 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003352 SSL_set_SSL_CTX(ssl, ctx);
3353 return SSL_TLSEXT_ERR_OK;
3354}
3355
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003356TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003357 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003358 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003359 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003360 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003361
David Benjamin0fef3052016-11-18 15:11:10 +09003362 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3363 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003364
David Benjamin83a32122017-02-14 18:34:54 -05003365 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3366 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3367
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003368 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3369 ASSERT_TRUE(server_ctx2);
3370 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3371 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3372 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3373 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3374 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3375 sizeof(kOCSPResponse)));
3376 // Historically signing preferences would be lost in some cases with the
3377 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3378 // this doesn't happen when |version| is TLS 1.2, configure the private
3379 // key to only sign SHA-256.
3380 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3381 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003382
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003383 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3384 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003385
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003386 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3387 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003388
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003389 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003390
David Benjamin0fef3052016-11-18 15:11:10 +09003391 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003392 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3393 ASSERT_TRUE(peer);
3394 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003395
David Benjamin83a32122017-02-14 18:34:54 -05003396 // The client should have received |server_ctx2|'s SCT list.
3397 const uint8_t *data;
3398 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003399 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3400 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003401
3402 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003403 SSL_get0_ocsp_response(client_.get(), &data, &len);
3404 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003405}
3406
David Benjaminf0d8e222017-02-04 10:58:26 -05003407// Test that the early callback can swap the maximum version.
3408TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003409 bssl::UniquePtr<SSL_CTX> server_ctx =
3410 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003411 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003412 ASSERT_TRUE(server_ctx);
3413 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003414 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3415 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003416
David Benjaminf0d8e222017-02-04 10:58:26 -05003417 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003418 server_ctx.get(),
3419 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003420 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003421 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003422 }
3423
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003424 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003425 });
David Benjamin99620572016-08-30 00:35:36 -04003426
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003427 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003428 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003429 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003430 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003431}
3432
David Benjaminf0d8e222017-02-04 10:58:26 -05003433TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003434 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003435 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003436
David Benjaminf0d8e222017-02-04 10:58:26 -05003437 // Set valid TLS versions.
3438 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3439 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3440 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3441 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003442
David Benjaminf0d8e222017-02-04 10:58:26 -05003443 // Invalid TLS versions are rejected.
3444 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3445 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3446 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3447 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3448 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3449 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003450
David Benjaminf0d8e222017-02-04 10:58:26 -05003451 // Zero is the default version.
3452 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003453 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003454 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003455 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003456
David Benjamin9bb15f52018-06-26 00:07:40 -04003457 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003458 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003459 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04003460
David Benjamin9bb15f52018-06-26 00:07:40 -04003461 // SSL 3.0 is not available.
3462 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3463
David Benjamin2dc02042016-09-19 19:57:37 -04003464 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003465 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003466
David Benjaminf0d8e222017-02-04 10:58:26 -05003467 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3468 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
3469 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3470 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003471
David Benjaminf0d8e222017-02-04 10:58:26 -05003472 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3473 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3474 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3475 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3476 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3477 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3478 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3479 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003480
David Benjaminf0d8e222017-02-04 10:58:26 -05003481 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003482 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003483 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003484 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003485}
3486
David Benjamin458334a2016-12-15 13:53:25 -05003487static const char *GetVersionName(uint16_t version) {
3488 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003489 case TLS1_VERSION:
3490 return "TLSv1";
3491 case TLS1_1_VERSION:
3492 return "TLSv1.1";
3493 case TLS1_2_VERSION:
3494 return "TLSv1.2";
3495 case TLS1_3_VERSION:
3496 return "TLSv1.3";
3497 case DTLS1_VERSION:
3498 return "DTLSv1";
3499 case DTLS1_2_VERSION:
3500 return "DTLSv1.2";
3501 default:
3502 return "???";
3503 }
3504}
3505
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003506TEST_P(SSLVersionTest, Version) {
3507 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003508
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003509 EXPECT_EQ(SSL_version(client_.get()), version());
3510 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003511
David Benjamin458334a2016-12-15 13:53:25 -05003512 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003513 const char *version_name = GetVersionName(version());
3514 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3515 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003516
3517 // Test SSL_SESSION reports the same name.
3518 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003519 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003520 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003521 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3522 EXPECT_EQ(strcmp(version_name, client_name), 0);
3523 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003524}
3525
David Benjamin9ef31f02016-10-31 18:01:13 -04003526// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3527// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003528TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003529 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3530
David Benjamin9ef31f02016-10-31 18:01:13 -04003531 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003532 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3533 sizeof(kALPNProtos)),
3534 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003535
3536 // The ALPN callback does not fail the handshake on error, so have the
3537 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003538 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003539 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003540 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003541 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3542 unsigned in_len, void *arg) -> int {
3543 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3544 if (SSL_get_pending_cipher(ssl) != nullptr &&
3545 SSL_version(ssl) == state->first) {
3546 state->second = true;
3547 }
3548 return SSL_TLSEXT_ERR_NOACK;
3549 },
3550 &callback_state);
3551
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003552 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003553
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003554 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003555}
3556
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003557TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003558 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3559 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003560 if (version() == TLS1_3_VERSION) {
3561 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003562 }
3563
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003564 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003565 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003566
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003567 EXPECT_FALSE(SSL_session_reused(client_.get()));
3568 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003569
3570 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003571 ASSERT_TRUE(SSL_clear(client_.get()));
3572 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003573
3574 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003575 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003576
3577 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003578 EXPECT_TRUE(SSL_session_reused(client_.get()));
3579 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003580}
3581
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003582TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3583 shed_handshake_config_ = false;
3584 ASSERT_TRUE(Connect());
3585 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3586
3587 // Reset everything.
3588 ASSERT_TRUE(SSL_clear(client_.get()));
3589 ASSERT_TRUE(SSL_clear(server_.get()));
3590
3591 // Now enable shedding, and connect a second time.
3592 shed_handshake_config_ = true;
3593 ASSERT_TRUE(Connect());
3594 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3595
3596 // |SSL_clear| should now fail.
3597 ASSERT_FALSE(SSL_clear(client_.get()));
3598 ASSERT_FALSE(SSL_clear(server_.get()));
3599}
3600
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003601static bool ChainsEqual(STACK_OF(X509) * chain,
3602 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003603 if (sk_X509_num(chain) != expected.size()) {
3604 return false;
3605 }
3606
3607 for (size_t i = 0; i < expected.size(); i++) {
3608 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3609 return false;
3610 }
3611 }
3612
3613 return true;
3614}
3615
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003616TEST_P(SSLVersionTest, AutoChain) {
3617 cert_ = GetChainTestCertificate();
3618 ASSERT_TRUE(cert_);
3619 key_ = GetChainTestKey();
3620 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003621 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003622 ASSERT_TRUE(intermediate);
3623
3624 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3625 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003626
3627 // Configure both client and server to accept any certificate. Add
3628 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003629 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3630 intermediate.get()));
3631 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3632 intermediate.get()));
3633 SSL_CTX_set_verify(client_ctx_.get(),
3634 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3635 nullptr);
3636 SSL_CTX_set_verify(server_ctx_.get(),
3637 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3638 nullptr);
3639 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3640 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003641
3642 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003643 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003644
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003645 EXPECT_TRUE(
3646 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3647 EXPECT_TRUE(
3648 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003649
3650 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003651 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3652 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3653 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003654
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003655 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3656 {cert_.get(), intermediate.get()}));
3657 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3658 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003659
3660 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003661 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3662 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3663 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003664
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003665 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3666 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003667
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003668 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3669 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003670}
3671
David Benjamin48063c22017-01-01 23:56:36 -05003672static bool ExpectBadWriteRetry() {
3673 int err = ERR_get_error();
3674 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3675 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3676 char buf[ERR_ERROR_STRING_BUF_LEN];
3677 ERR_error_string_n(err, buf, sizeof(buf));
3678 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3679 return false;
3680 }
3681
3682 if (ERR_peek_error() != 0) {
3683 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3684 return false;
3685 }
3686
3687 return true;
3688}
3689
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003690TEST_P(SSLVersionTest, SSLWriteRetry) {
3691 if (is_dtls()) {
3692 return;
David Benjamin48063c22017-01-01 23:56:36 -05003693 }
3694
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003695 for (bool enable_partial_write : {false, true}) {
3696 SCOPED_TRACE(enable_partial_write);
3697
David Benjamin48063c22017-01-01 23:56:36 -05003698 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003699 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3700
3701 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003702
3703 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003704 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003705 }
3706
3707 // Write without reading until the buffer is full and we have an unfinished
3708 // write. Keep a count so we may reread it again later. "hello!" will be
3709 // written in two chunks, "hello" and "!".
3710 char data[] = "hello!";
3711 static const int kChunkLen = 5; // The length of "hello".
3712 unsigned count = 0;
3713 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003714 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003715 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003716 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3717 break;
David Benjamin48063c22017-01-01 23:56:36 -05003718 }
3719
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003720 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003721
3722 count++;
3723 }
3724
3725 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003726 ASSERT_EQ(
3727 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3728 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003729
3730 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003731 ASSERT_EQ(SSL_get_error(client_.get(),
3732 SSL_write(client_.get(), data, kChunkLen - 1)),
3733 SSL_ERROR_SSL);
3734 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003735
3736 // Retrying with a different buffer pointer is not legal.
3737 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003738 ASSERT_EQ(SSL_get_error(client_.get(),
3739 SSL_write(client_.get(), data2, kChunkLen)),
3740 SSL_ERROR_SSL);
3741 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003742
3743 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003744 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3745 ASSERT_EQ(SSL_get_error(client_.get(),
3746 SSL_write(client_.get(), data2, kChunkLen)),
3747 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003748
3749 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003750 ASSERT_EQ(SSL_get_error(client_.get(),
3751 SSL_write(client_.get(), data2, kChunkLen - 1)),
3752 SSL_ERROR_SSL);
3753 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003754
3755 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003756 ASSERT_EQ(SSL_get_error(client_.get(),
3757 SSL_write(client_.get(), data, kChunkLen + 1)),
3758 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003759
3760 // Drain the buffer.
3761 char buf[20];
3762 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003763 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3764 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003765 }
3766
3767 // Now that there is space, a retry with a larger buffer should flush the
3768 // pending record, skip over that many bytes of input (on assumption they
3769 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3770 // is set, this will complete in two steps.
3771 char data3[] = "_____!";
3772 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003773 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3774 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3775 } else {
3776 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003777 }
3778
3779 // Check the last write was correct. The data will be spread over two
3780 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003781 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3782 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3783 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3784 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003785 }
David Benjamin48063c22017-01-01 23:56:36 -05003786}
3787
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003788TEST_P(SSLVersionTest, RecordCallback) {
3789 for (bool test_server : {true, false}) {
3790 SCOPED_TRACE(test_server);
3791 ResetContexts();
David Benjamin5df5be1a2017-06-22 19:43:11 -04003792
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003793 bool read_seen = false;
3794 bool write_seen = false;
3795 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3796 size_t len, SSL *ssl) {
3797 if (cb_type != SSL3_RT_HEADER) {
3798 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003799 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003800
3801 // The callback does not report a version for records.
3802 EXPECT_EQ(0, cb_version);
3803
3804 if (is_write) {
3805 write_seen = true;
3806 } else {
3807 read_seen = true;
3808 }
3809
3810 // Sanity-check that the record header is plausible.
3811 CBS cbs;
3812 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3813 uint8_t type;
3814 uint16_t record_version, length;
3815 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3816 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003817 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003818 if (is_dtls()) {
3819 uint16_t epoch;
3820 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3821 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3822 ASSERT_TRUE(CBS_skip(&cbs, 6));
3823 }
3824 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3825 EXPECT_EQ(0u, CBS_len(&cbs));
3826 };
3827 using CallbackType = decltype(cb);
3828 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3829 SSL_CTX_set_msg_callback(
3830 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3831 size_t len, SSL *ssl, void *arg) {
3832 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3833 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3834 });
3835 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3836
3837 ASSERT_TRUE(Connect());
3838
3839 EXPECT_TRUE(read_seen);
3840 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003841 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003842}
3843
David Benjamina8614602017-09-06 15:40:19 -04003844TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003845 ClientConfig config;
3846 config.servername = "host1";
3847
3848 SSL_CTX_set_tlsext_servername_callback(
3849 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3850 // During the handshake, |SSL_get_servername| must match |config|.
3851 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3852 EXPECT_STREQ(config_p->servername.c_str(),
3853 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3854 return SSL_TLSEXT_ERR_OK;
3855 });
3856 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3857
3858 ASSERT_TRUE(Connect(config));
3859 // After the handshake, it must also be available.
3860 EXPECT_STREQ(config.servername.c_str(),
3861 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3862
3863 // Establish a session under host1.
3864 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3865 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3866 bssl::UniquePtr<SSL_SESSION> session =
3867 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3868
3869 // If the client resumes a session with a different name, |SSL_get_servername|
3870 // must return the new name.
3871 ASSERT_TRUE(session);
3872 config.session = session.get();
3873 config.servername = "host2";
3874 ASSERT_TRUE(Connect(config));
3875 EXPECT_STREQ(config.servername.c_str(),
3876 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3877}
3878
David Benjamin3d8f0802017-09-06 16:12:52 -04003879// Test that session cache mode bits are honored in the client session callback.
3880TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3881 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3882 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3883
3884 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3885 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3886
3887 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3888 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3889}
3890
Steven Valdez777a2392019-02-21 11:30:47 -05003891// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3892// NewSessionTickets are written post-handshake. Servers that block
3893// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3894// the buffer. Test that we do not do this.
3895TEST_P(SSLVersionTest, SmallBuffer) {
3896 // DTLS is a datagram protocol and requires packet-sized buffers.
3897 if (is_dtls()) {
3898 return;
3899 }
3900
3901 // Test both flushing NewSessionTickets with a zero-sized write and
3902 // non-zero-sized write.
3903 for (bool use_zero_write : {false, true}) {
3904 SCOPED_TRACE(use_zero_write);
3905
3906 g_last_session = nullptr;
3907 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3908 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3909
3910 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3911 server(SSL_new(server_ctx_.get()));
3912 ASSERT_TRUE(client);
3913 ASSERT_TRUE(server);
3914 SSL_set_connect_state(client.get());
3915 SSL_set_accept_state(server.get());
3916
3917 // Use a tiny buffer.
3918 BIO *bio1, *bio2;
3919 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3920
3921 // SSL_set_bio takes ownership.
3922 SSL_set_bio(client.get(), bio1, bio1);
3923 SSL_set_bio(server.get(), bio2, bio2);
3924
3925 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3926 if (version() >= TLS1_3_VERSION) {
3927 // The post-handshake ticket should not have been processed yet.
3928 EXPECT_FALSE(g_last_session);
3929 }
3930
3931 if (use_zero_write) {
3932 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3933 EXPECT_TRUE(g_last_session);
3934 }
3935
3936 // Send some data from server to client. If |use_zero_write| is false, this
3937 // will also flush the NewSessionTickets.
3938 static const char kMessage[] = "hello world";
3939 char buf[sizeof(kMessage)];
3940 for (;;) {
3941 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3942 int server_err = SSL_get_error(server.get(), server_ret);
3943 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3944 int client_err = SSL_get_error(client.get(), client_ret);
3945
3946 // The server will write a single record, so every iteration should see
3947 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3948 // iteration, where both will complete.
3949 if (server_ret > 0) {
3950 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3951 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3952 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3953 break;
3954 }
3955
3956 ASSERT_EQ(server_ret, -1);
3957 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3958 ASSERT_EQ(client_ret, -1);
3959 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3960 }
3961
3962 // The NewSessionTickets should have been flushed and processed.
3963 EXPECT_TRUE(g_last_session);
3964 }
3965}
3966
Adam Langleye1e78132017-01-31 15:24:31 -08003967TEST(SSLTest, AddChainCertHack) {
3968 // Ensure that we don't accidently break the hack that we have in place to
3969 // keep curl and serf happy when they use an |X509| even after transfering
3970 // ownership.
3971
3972 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3973 ASSERT_TRUE(ctx);
3974 X509 *cert = GetTestCertificate().release();
3975 ASSERT_TRUE(cert);
3976 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3977
3978 // This should not trigger a use-after-free.
3979 X509_cmp(cert, cert);
3980}
3981
David Benjaminb2ff2622017-02-03 17:06:18 -05003982TEST(SSLTest, GetCertificate) {
3983 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3984 ASSERT_TRUE(ctx);
3985 bssl::UniquePtr<X509> cert = GetTestCertificate();
3986 ASSERT_TRUE(cert);
3987 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3988 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3989 ASSERT_TRUE(ssl);
3990
3991 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3992 ASSERT_TRUE(cert2);
3993 X509 *cert3 = SSL_get_certificate(ssl.get());
3994 ASSERT_TRUE(cert3);
3995
3996 // The old and new certificates must be identical.
3997 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3998 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3999
4000 uint8_t *der = nullptr;
4001 long der_len = i2d_X509(cert.get(), &der);
4002 ASSERT_LT(0, der_len);
4003 bssl::UniquePtr<uint8_t> free_der(der);
4004
4005 uint8_t *der2 = nullptr;
4006 long der2_len = i2d_X509(cert2, &der2);
4007 ASSERT_LT(0, der2_len);
4008 bssl::UniquePtr<uint8_t> free_der2(der2);
4009
4010 uint8_t *der3 = nullptr;
4011 long der3_len = i2d_X509(cert3, &der3);
4012 ASSERT_LT(0, der3_len);
4013 bssl::UniquePtr<uint8_t> free_der3(der3);
4014
4015 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05004016 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4017 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05004018}
4019
Adam Langleyd04ca952017-02-28 11:26:51 -08004020TEST(SSLTest, SetChainAndKeyMismatch) {
4021 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4022 ASSERT_TRUE(ctx);
4023
4024 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4025 ASSERT_TRUE(key);
4026 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4027 ASSERT_TRUE(leaf);
4028 std::vector<CRYPTO_BUFFER*> chain = {
4029 leaf.get(),
4030 };
4031
4032 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
4033 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
4034 key.get(), nullptr));
4035 ERR_clear_error();
4036}
4037
4038TEST(SSLTest, SetChainAndKey) {
4039 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4040 ASSERT_TRUE(client_ctx);
4041 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4042 ASSERT_TRUE(server_ctx);
4043
Adam Langley964256d2020-03-19 11:57:12 -07004044 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4045
Adam Langleyd04ca952017-02-28 11:26:51 -08004046 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4047 ASSERT_TRUE(key);
4048 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4049 ASSERT_TRUE(leaf);
4050 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4051 GetChainTestIntermediateBuffer();
4052 ASSERT_TRUE(intermediate);
4053 std::vector<CRYPTO_BUFFER*> chain = {
4054 leaf.get(), intermediate.get(),
4055 };
4056 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4057 chain.size(), key.get(), nullptr));
4058
Adam Langley964256d2020-03-19 11:57:12 -07004059 ASSERT_EQ(chain.size(),
4060 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4061
David Benjamin3a1dd462017-07-11 16:13:10 -04004062 SSL_CTX_set_custom_verify(
4063 client_ctx.get(), SSL_VERIFY_PEER,
4064 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4065 return ssl_verify_ok;
4066 });
Adam Langleyd04ca952017-02-28 11:26:51 -08004067
4068 bssl::UniquePtr<SSL> client, server;
4069 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004070 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08004071}
4072
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004073TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4074 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4075 ASSERT_TRUE(client_ctx);
4076 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4077 ASSERT_TRUE(server_ctx);
4078
4079 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4080 ASSERT_TRUE(key);
4081 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4082 ASSERT_TRUE(leaf);
4083 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4084 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4085 chain.size(), key.get(), nullptr));
4086
4087 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4088 // configuration, certificate verification should fail.
4089 bssl::UniquePtr<SSL> client, server;
4090 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4091 server_ctx.get()));
4092
4093 // Whereas with a verifier, the connection should succeed.
4094 SSL_CTX_set_custom_verify(
4095 client_ctx.get(), SSL_VERIFY_PEER,
4096 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4097 return ssl_verify_ok;
4098 });
4099 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4100 server_ctx.get()));
4101}
4102
4103TEST(SSLTest, CustomVerify) {
4104 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4105 ASSERT_TRUE(client_ctx);
4106 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4107 ASSERT_TRUE(server_ctx);
4108
4109 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4110 ASSERT_TRUE(key);
4111 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4112 ASSERT_TRUE(leaf);
4113 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4114 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4115 chain.size(), key.get(), nullptr));
4116
4117 SSL_CTX_set_custom_verify(
4118 client_ctx.get(), SSL_VERIFY_PEER,
4119 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4120 return ssl_verify_ok;
4121 });
4122
4123 bssl::UniquePtr<SSL> client, server;
4124 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4125 server_ctx.get()));
4126
4127 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4128 // connection.
4129 SSL_CTX_set_custom_verify(
4130 client_ctx.get(), SSL_VERIFY_PEER,
4131 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4132 return ssl_verify_invalid;
4133 });
4134
4135 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4136 server_ctx.get()));
4137
4138 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4139 // connection.
4140 SSL_CTX_set_custom_verify(
4141 client_ctx.get(), SSL_VERIFY_NONE,
4142 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4143 return ssl_verify_invalid;
4144 });
4145
4146 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4147 server_ctx.get()));
4148}
4149
David Benjamin71dfad42017-07-16 17:27:39 -04004150TEST(SSLTest, ClientCABuffers) {
4151 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4152 ASSERT_TRUE(client_ctx);
4153 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4154 ASSERT_TRUE(server_ctx);
4155
4156 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4157 ASSERT_TRUE(key);
4158 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4159 ASSERT_TRUE(leaf);
4160 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4161 GetChainTestIntermediateBuffer();
4162 ASSERT_TRUE(intermediate);
4163 std::vector<CRYPTO_BUFFER *> chain = {
4164 leaf.get(),
4165 intermediate.get(),
4166 };
4167 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4168 chain.size(), key.get(), nullptr));
4169
4170 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4171 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4172 ASSERT_TRUE(ca_name);
4173 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4174 sk_CRYPTO_BUFFER_new_null());
4175 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04004176 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04004177 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
4178
4179 // Configure client and server to accept all certificates.
4180 SSL_CTX_set_custom_verify(
4181 client_ctx.get(), SSL_VERIFY_PEER,
4182 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4183 return ssl_verify_ok;
4184 });
4185 SSL_CTX_set_custom_verify(
4186 server_ctx.get(), SSL_VERIFY_PEER,
4187 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4188 return ssl_verify_ok;
4189 });
4190
4191 bool cert_cb_called = false;
4192 SSL_CTX_set_cert_cb(
4193 client_ctx.get(),
4194 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04004195 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04004196 SSL_get0_server_requested_CAs(ssl);
4197 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
4198 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
4199 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
4200 CRYPTO_BUFFER_len(peer_name)));
4201 *reinterpret_cast<bool *>(arg) = true;
4202 return 1;
4203 },
4204 &cert_cb_called);
4205
4206 bssl::UniquePtr<SSL> client, server;
4207 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004208 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04004209 EXPECT_TRUE(cert_cb_called);
4210}
4211
David Benjamin91222b82017-03-09 20:10:56 -05004212// Configuring the empty cipher list, though an error, should still modify the
4213// configuration.
4214TEST(SSLTest, EmptyCipherList) {
4215 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4216 ASSERT_TRUE(ctx);
4217
4218 // Initially, the cipher list is not empty.
4219 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4220
4221 // Configuring the empty cipher list fails.
4222 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4223 ERR_clear_error();
4224
4225 // But the cipher list is still updated to empty.
4226 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4227}
4228
Adam Langley4c341d02017-03-08 19:33:21 -08004229// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4230// test |SSL_TICKET_AEAD_METHOD| can fail.
4231enum ssl_test_ticket_aead_failure_mode {
4232 ssl_test_ticket_aead_ok = 0,
4233 ssl_test_ticket_aead_seal_fail,
4234 ssl_test_ticket_aead_open_soft_fail,
4235 ssl_test_ticket_aead_open_hard_fail,
4236};
4237
4238struct ssl_test_ticket_aead_state {
4239 unsigned retry_count;
4240 ssl_test_ticket_aead_failure_mode failure_mode;
4241};
4242
4243static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4244 const CRYPTO_EX_DATA *from,
4245 void **from_d, int index,
4246 long argl, void *argp) {
4247 abort();
4248}
4249
4250static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4251 CRYPTO_EX_DATA *ad, int index,
4252 long argl, void *argp) {
4253 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4254 if (state == nullptr) {
4255 return;
4256 }
4257
4258 OPENSSL_free(state);
4259}
4260
4261static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4262static int g_ssl_test_ticket_aead_ex_index;
4263
4264static int ssl_test_ticket_aead_get_ex_index() {
4265 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4266 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4267 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4268 ssl_test_ticket_aead_ex_index_free);
4269 });
4270 return g_ssl_test_ticket_aead_ex_index;
4271}
4272
4273static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4274 return 1;
4275}
4276
4277static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4278 size_t max_out_len, const uint8_t *in,
4279 size_t in_len) {
4280 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4281 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4282
4283 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4284 max_out_len < in_len + 1) {
4285 return 0;
4286 }
4287
4288 OPENSSL_memmove(out, in, in_len);
4289 out[in_len] = 0xff;
4290 *out_len = in_len + 1;
4291
4292 return 1;
4293}
4294
4295static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4296 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4297 const uint8_t *in, size_t in_len) {
4298 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4299 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4300
4301 if (state->retry_count > 0) {
4302 state->retry_count--;
4303 return ssl_ticket_aead_retry;
4304 }
4305
4306 switch (state->failure_mode) {
4307 case ssl_test_ticket_aead_ok:
4308 break;
4309 case ssl_test_ticket_aead_seal_fail:
4310 // If |seal| failed then there shouldn't be any ticket to try and
4311 // decrypt.
4312 abort();
4313 break;
4314 case ssl_test_ticket_aead_open_soft_fail:
4315 return ssl_ticket_aead_ignore_ticket;
4316 case ssl_test_ticket_aead_open_hard_fail:
4317 return ssl_ticket_aead_error;
4318 }
4319
4320 if (in_len == 0 || in[in_len - 1] != 0xff) {
4321 return ssl_ticket_aead_ignore_ticket;
4322 }
4323
4324 if (max_out_len < in_len - 1) {
4325 return ssl_ticket_aead_error;
4326 }
4327
4328 OPENSSL_memmove(out, in, in_len - 1);
4329 *out_len = in_len - 1;
4330 return ssl_ticket_aead_success;
4331}
4332
4333static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4334 ssl_test_ticket_aead_max_overhead,
4335 ssl_test_ticket_aead_seal,
4336 ssl_test_ticket_aead_open,
4337};
4338
4339static void ConnectClientAndServerWithTicketMethod(
4340 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4341 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4342 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4343 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4344 ASSERT_TRUE(client);
4345 ASSERT_TRUE(server);
4346 SSL_set_connect_state(client.get());
4347 SSL_set_accept_state(server.get());
4348
4349 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4350 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4351 ASSERT_TRUE(state);
4352 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4353 state->retry_count = retry_count;
4354 state->failure_mode = failure_mode;
4355
4356 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4357 state));
4358
4359 SSL_set_session(client.get(), session);
4360
4361 BIO *bio1, *bio2;
4362 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4363
4364 // SSL_set_bio takes ownership.
4365 SSL_set_bio(client.get(), bio1, bio1);
4366 SSL_set_bio(server.get(), bio2, bio2);
4367
4368 if (CompleteHandshakes(client.get(), server.get())) {
4369 *out_client = std::move(client);
4370 *out_server = std::move(server);
4371 } else {
4372 out_client->reset();
4373 out_server->reset();
4374 }
4375}
4376
David Benjaminc9775322018-04-13 16:39:12 -04004377using TicketAEADMethodParam =
4378 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4379
Adam Langley4c341d02017-03-08 19:33:21 -08004380class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004381 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004382
4383TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004384 bssl::UniquePtr<SSL_CTX> server_ctx =
4385 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004386 ASSERT_TRUE(server_ctx);
4387 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4388 ASSERT_TRUE(client_ctx);
4389
4390 const uint16_t version = testing::get<0>(GetParam());
4391 const unsigned retry_count = testing::get<1>(GetParam());
4392 const ssl_test_ticket_aead_failure_mode failure_mode =
4393 testing::get<2>(GetParam());
4394
Adam Langley4c341d02017-03-08 19:33:21 -08004395 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4396 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4397 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4398 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4399
4400 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4401 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4402 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4403 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004404 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004405
4406 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4407
4408 bssl::UniquePtr<SSL> client, server;
4409 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4410 server_ctx.get(), retry_count,
4411 failure_mode, nullptr);
4412 switch (failure_mode) {
4413 case ssl_test_ticket_aead_ok:
4414 case ssl_test_ticket_aead_open_hard_fail:
4415 case ssl_test_ticket_aead_open_soft_fail:
4416 ASSERT_TRUE(client);
4417 break;
4418 case ssl_test_ticket_aead_seal_fail:
4419 EXPECT_FALSE(client);
4420 return;
4421 }
4422 EXPECT_FALSE(SSL_session_reused(client.get()));
4423 EXPECT_FALSE(SSL_session_reused(server.get()));
4424
Steven Valdez777a2392019-02-21 11:30:47 -05004425 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004426 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004427 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4428 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004429 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004430 switch (failure_mode) {
4431 case ssl_test_ticket_aead_ok:
4432 ASSERT_TRUE(client);
4433 EXPECT_TRUE(SSL_session_reused(client.get()));
4434 EXPECT_TRUE(SSL_session_reused(server.get()));
4435 break;
4436 case ssl_test_ticket_aead_seal_fail:
4437 abort();
4438 break;
4439 case ssl_test_ticket_aead_open_hard_fail:
4440 EXPECT_FALSE(client);
4441 break;
4442 case ssl_test_ticket_aead_open_soft_fail:
4443 ASSERT_TRUE(client);
4444 EXPECT_FALSE(SSL_session_reused(client.get()));
4445 EXPECT_FALSE(SSL_session_reused(server.get()));
4446 }
4447}
4448
David Benjaminc9775322018-04-13 16:39:12 -04004449std::string TicketAEADMethodParamToString(
4450 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4451 std::string ret = GetVersionName(std::get<0>(params.param));
4452 // GTest only allows alphanumeric characters and '_' in the parameter
4453 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4454 for (auto it = ret.begin(); it != ret.end();) {
4455 if (*it == '.' || *it == 'v') {
4456 it = ret.erase(it);
4457 } else {
4458 ++it;
4459 }
4460 }
4461 char retry_count[256];
4462 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
4463 ret += "_";
4464 ret += retry_count;
4465 ret += "Retries_";
4466 switch (std::get<2>(params.param)) {
4467 case ssl_test_ticket_aead_ok:
4468 ret += "OK";
4469 break;
4470 case ssl_test_ticket_aead_seal_fail:
4471 ret += "SealFail";
4472 break;
4473 case ssl_test_ticket_aead_open_soft_fail:
4474 ret += "OpenSoftFail";
4475 break;
4476 case ssl_test_ticket_aead_open_hard_fail:
4477 ret += "OpenHardFail";
4478 break;
4479 }
4480 return ret;
4481}
4482
David Benjaminbe7006a2019-04-09 18:05:02 -05004483INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004484 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004485 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4486 testing::Values(0, 1, 2),
4487 testing::Values(ssl_test_ticket_aead_ok,
4488 ssl_test_ticket_aead_seal_fail,
4489 ssl_test_ticket_aead_open_soft_fail,
4490 ssl_test_ticket_aead_open_hard_fail)),
4491 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004492
David Benjaminca743582017-06-15 17:51:35 -04004493TEST(SSLTest, SelectNextProto) {
4494 uint8_t *result;
4495 uint8_t result_len;
4496
4497 // If there is an overlap, it should be returned.
4498 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4499 SSL_select_next_proto(&result, &result_len,
4500 (const uint8_t *)"\1a\2bb\3ccc", 9,
4501 (const uint8_t *)"\1x\1y\1a\1z", 8));
4502 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4503
4504 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4505 SSL_select_next_proto(&result, &result_len,
4506 (const uint8_t *)"\1a\2bb\3ccc", 9,
4507 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4508 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4509
4510 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4511 SSL_select_next_proto(&result, &result_len,
4512 (const uint8_t *)"\1a\2bb\3ccc", 9,
4513 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4514 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4515
4516 // Peer preference order takes precedence over local.
4517 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4518 SSL_select_next_proto(&result, &result_len,
4519 (const uint8_t *)"\1a\2bb\3ccc", 9,
4520 (const uint8_t *)"\3ccc\2bb\1a", 9));
4521 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4522
4523 // If there is no overlap, return the first local protocol.
4524 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4525 SSL_select_next_proto(&result, &result_len,
4526 (const uint8_t *)"\1a\2bb\3ccc", 9,
4527 (const uint8_t *)"\1x\2yy\3zzz", 9));
4528 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4529
4530 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4531 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4532 (const uint8_t *)"\1x\2yy\3zzz", 9));
4533 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4534}
4535
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004536TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004537 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004538 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004539 ASSERT_TRUE(client_ctx);
4540 ASSERT_TRUE(server_ctx);
4541
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004542 bssl::UniquePtr<SSL> client, server;
4543 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004544 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004545
4546 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4547 std::vector<uint8_t> prefix(
4548 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004549 body(record.size()),
4550 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004551 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4552 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004553 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004554
4555 std::vector<uint8_t> sealed;
4556 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4557 sealed.insert(sealed.end(), body.begin(), body.end());
4558 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4559 std::vector<uint8_t> sealed_copy = sealed;
4560
4561 bssl::Span<uint8_t> plaintext;
4562 size_t record_len;
4563 uint8_t alert = 255;
4564 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4565 bssl::MakeSpan(sealed)),
4566 bssl::OpenRecordResult::kOK);
4567 EXPECT_EQ(record_len, sealed.size());
4568 EXPECT_EQ(plaintext, record);
4569 EXPECT_EQ(255, alert);
4570}
4571
4572TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004573 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004574 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004575 ASSERT_TRUE(client_ctx);
4576 ASSERT_TRUE(server_ctx);
4577
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004578 bssl::UniquePtr<SSL> client, server;
4579 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004580 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004581
4582 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4583 std::vector<uint8_t> record = plaintext;
4584 std::vector<uint8_t> prefix(
4585 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004586 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004587 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4588 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004589 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004590 record.insert(record.begin(), prefix.begin(), prefix.end());
4591 record.insert(record.end(), suffix.begin(), suffix.end());
4592
4593 bssl::Span<uint8_t> result;
4594 size_t record_len;
4595 uint8_t alert;
4596 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4597 bssl::MakeSpan(record)),
4598 bssl::OpenRecordResult::kOK);
4599 EXPECT_EQ(record_len, record.size());
4600 EXPECT_EQ(plaintext, result);
4601}
4602
4603TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004604 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004605 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004606 ASSERT_TRUE(client_ctx);
4607 ASSERT_TRUE(server_ctx);
4608
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004609 bssl::UniquePtr<SSL> client, server;
4610 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004611 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004612
4613 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4614 std::vector<uint8_t> record = plaintext;
4615 std::vector<uint8_t> prefix(
4616 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004617 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004618 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4619 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004620 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004621 record.insert(record.begin(), prefix.begin(), prefix.end());
4622 record.insert(record.end(), suffix.begin(), suffix.end());
4623 record.insert(record.end(), {5, 4, 3, 2, 1});
4624
4625 bssl::Span<uint8_t> result;
4626 size_t record_len;
4627 uint8_t alert;
4628 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4629 bssl::MakeSpan(record)),
4630 bssl::OpenRecordResult::kOK);
4631 EXPECT_EQ(record_len, record.size() - 5);
4632 EXPECT_EQ(plaintext, result);
4633}
4634
4635TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004636 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004637 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004638 ASSERT_TRUE(client_ctx);
4639 ASSERT_TRUE(server_ctx);
4640
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004641 bssl::UniquePtr<SSL> client, server;
4642 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004643 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004644
4645 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4646 std::vector<uint8_t> prefix(
4647 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004648 body(record.size()),
4649 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004650
4651 auto expect_err = []() {
4652 int err = ERR_get_error();
4653 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4654 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4655 ERR_clear_error();
4656 };
4657 EXPECT_FALSE(bssl::SealRecord(
4658 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004659 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004660 expect_err();
4661 EXPECT_FALSE(bssl::SealRecord(
4662 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004663 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004664 expect_err();
4665
4666 EXPECT_FALSE(
4667 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4668 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004669 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004670 expect_err();
4671 EXPECT_FALSE(
4672 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4673 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004674 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004675 expect_err();
4676
4677 EXPECT_FALSE(bssl::SealRecord(
4678 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004679 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004680 expect_err();
4681 EXPECT_FALSE(bssl::SealRecord(
4682 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004683 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004684 expect_err();
4685}
4686
David Benjamin617b8182017-08-29 15:33:10 -04004687// The client should gracefully handle no suitable ciphers being enabled.
4688TEST(SSLTest, NoCiphersAvailable) {
4689 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4690 ASSERT_TRUE(ctx);
4691
4692 // Configure |client_ctx| with a cipher list that does not intersect with its
4693 // version configuration.
4694 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4695 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4696 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4697
4698 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4699 ASSERT_TRUE(ssl);
4700 SSL_set_connect_state(ssl.get());
4701
4702 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4703 ASSERT_TRUE(rbio);
4704 ASSERT_TRUE(wbio);
4705 SSL_set0_rbio(ssl.get(), rbio.release());
4706 SSL_set0_wbio(ssl.get(), wbio.release());
4707
4708 int ret = SSL_do_handshake(ssl.get());
4709 EXPECT_EQ(-1, ret);
4710 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4711 uint32_t err = ERR_get_error();
4712 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4713 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4714}
4715
David Benjamina4bafd32017-10-03 15:06:29 -04004716TEST_P(SSLVersionTest, SessionVersion) {
4717 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4718 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4719
4720 bssl::UniquePtr<SSL_SESSION> session =
4721 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4722 ASSERT_TRUE(session);
4723 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4724
4725 // Sessions in TLS 1.3 and later should be single-use.
4726 EXPECT_EQ(version() == TLS1_3_VERSION,
4727 !!SSL_SESSION_should_be_single_use(session.get()));
4728
4729 // Making fake sessions for testing works.
4730 session.reset(SSL_SESSION_new(client_ctx_.get()));
4731 ASSERT_TRUE(session);
4732 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4733 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4734}
4735
David Benjaminfdb7a352017-10-12 17:34:18 -04004736TEST_P(SSLVersionTest, SSLPending) {
4737 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4738 ASSERT_TRUE(ssl);
4739 EXPECT_EQ(0, SSL_pending(ssl.get()));
4740
4741 ASSERT_TRUE(Connect());
4742 EXPECT_EQ(0, SSL_pending(client_.get()));
4743
4744 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4745 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4746 EXPECT_EQ(0, SSL_pending(client_.get()));
4747
4748 char buf[10];
4749 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4750 EXPECT_EQ(5, SSL_pending(client_.get()));
4751
4752 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4753 EXPECT_EQ(4, SSL_pending(client_.get()));
4754
4755 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4756 EXPECT_EQ(0, SSL_pending(client_.get()));
4757
4758 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4759 EXPECT_EQ(3, SSL_pending(client_.get()));
4760}
4761
David Benjamina031b612017-10-11 20:48:25 -04004762// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4763TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004764 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004765 ASSERT_TRUE(ctx);
4766 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4767 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4768
David Benjamina031b612017-10-11 20:48:25 -04004769 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4770
4771 bssl::UniquePtr<SSL> client, server;
4772 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4773
4774 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4775 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4776 return 0;
4777 });
4778
4779 // Send close_notify.
4780 EXPECT_EQ(0, SSL_shutdown(server.get()));
4781 EXPECT_EQ(0, SSL_shutdown(client.get()));
4782
4783 // Receive close_notify.
4784 EXPECT_EQ(1, SSL_shutdown(server.get()));
4785 EXPECT_EQ(1, SSL_shutdown(client.get()));
4786}
4787
David Benjamin6cc352e2017-11-02 17:21:39 -04004788TEST(SSLTest, SignatureAlgorithmProperties) {
4789 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4790 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4791 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4792
4793 EXPECT_EQ(EVP_PKEY_RSA,
4794 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4795 EXPECT_EQ(EVP_md5_sha1(),
4796 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4797 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4798
4799 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4800 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4801 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4802 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4803 EXPECT_FALSE(
4804 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4805
4806 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004807 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004808 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004809 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4810 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004811}
4812
Adam Langley85967952018-07-03 08:04:58 -07004813static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4814 size_t in_len) {
4815 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004816 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004817 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004818 }
4819 }
4820
4821 SSL_set_app_data(ssl, XORCompressFunc);
4822
Adam Langley85967952018-07-03 08:04:58 -07004823 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004824}
4825
Adam Langley85967952018-07-03 08:04:58 -07004826static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4827 size_t uncompressed_len, const uint8_t *in,
4828 size_t in_len) {
4829 if (in_len != uncompressed_len) {
4830 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004831 }
4832
4833 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004834 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4835 if (*out == nullptr) {
4836 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004837 }
4838
Adam Langley85967952018-07-03 08:04:58 -07004839 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004840 data[i] = in[i] ^ 0x55;
4841 }
4842
4843 SSL_set_app_data(ssl, XORDecompressFunc);
4844
Adam Langley85967952018-07-03 08:04:58 -07004845 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004846}
4847
4848TEST(SSLTest, CertCompression) {
4849 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004850 bssl::UniquePtr<SSL_CTX> server_ctx(
4851 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004852 ASSERT_TRUE(client_ctx);
4853 ASSERT_TRUE(server_ctx);
4854
Adam Langley0080d832018-06-07 16:39:49 -07004855 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4856 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4857 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4858 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4859 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4860 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4861
4862 bssl::UniquePtr<SSL> client, server;
4863 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4864 server_ctx.get()));
4865
4866 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4867 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4868}
4869
Adam Langleyddb57cf2018-01-26 09:17:53 -08004870void MoveBIOs(SSL *dest, SSL *src) {
4871 BIO *rbio = SSL_get_rbio(src);
4872 BIO_up_ref(rbio);
4873 SSL_set0_rbio(dest, rbio);
4874
4875 BIO *wbio = SSL_get_wbio(src);
4876 BIO_up_ref(wbio);
4877 SSL_set0_wbio(dest, wbio);
4878
4879 SSL_set0_rbio(src, nullptr);
4880 SSL_set0_wbio(src, nullptr);
4881}
4882
4883TEST(SSLTest, Handoff) {
4884 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4885 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004886 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4887 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004888 ASSERT_TRUE(client_ctx);
4889 ASSERT_TRUE(server_ctx);
4890 ASSERT_TRUE(handshaker_ctx);
4891
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004892 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4893 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004894 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004895 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004896 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004897 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004898
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004899 for (bool early_data : {false, true}) {
4900 SCOPED_TRACE(early_data);
4901 for (bool is_resume : {false, true}) {
4902 SCOPED_TRACE(is_resume);
4903 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004904 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4905 server_ctx.get()));
4906 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004907 if (is_resume) {
4908 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004909 SSL_set_session(client.get(), g_last_session.get());
4910 if (early_data) {
4911 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4912 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004913 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004914
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004915
4916 int client_ret = SSL_do_handshake(client.get());
4917 int client_err = SSL_get_error(client.get(), client_ret);
4918
4919 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004920 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004921 ASSERT_EQ(client_err, 0);
4922 EXPECT_TRUE(SSL_in_early_data(client.get()));
4923 // Attempt to write early data.
4924 byte_written = 43;
4925 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4926 } else {
4927 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4928 }
4929
4930 int server_ret = SSL_do_handshake(server.get());
4931 int server_err = SSL_get_error(server.get(), server_ret);
4932 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4933
4934 ScopedCBB cbb;
4935 Array<uint8_t> handoff;
4936 SSL_CLIENT_HELLO hello;
4937 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4938 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4939 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4940
4941 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4942 // Note split handshakes determines 0-RTT support, for both the current
4943 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4944 // no need to call |SSL_set_early_data_enabled| on |server|.
4945 SSL_set_early_data_enabled(handshaker.get(), 1);
4946 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4947
4948 MoveBIOs(handshaker.get(), server.get());
4949
4950 int handshake_ret = SSL_do_handshake(handshaker.get());
4951 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4952 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4953
4954 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004955 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004956 handshake_ret = SSL_do_handshake(handshaker.get());
4957 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4958 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4959
4960 ScopedCBB cbb_handback;
4961 Array<uint8_t> handback;
4962 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4963 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4964 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4965
4966 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4967 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4968
4969 MoveBIOs(server2.get(), handshaker.get());
4970 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4971 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4972
David Benjamin9b2cdb72021-04-01 23:21:53 -04004973 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004974 // In this case, one byte of early data has already been written above.
4975 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4976 } else {
4977 byte_written = 42;
4978 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4979 }
4980 uint8_t byte;
4981 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4982 EXPECT_EQ(byte_written, byte);
4983
4984 byte = 44;
4985 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4986 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4987 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004988 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004989 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004990}
4991
4992TEST(SSLTest, HandoffDeclined) {
4993 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004994 bssl::UniquePtr<SSL_CTX> server_ctx(
4995 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004996 ASSERT_TRUE(client_ctx);
4997 ASSERT_TRUE(server_ctx);
4998
4999 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
5000 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5001
Adam Langleyddb57cf2018-01-26 09:17:53 -08005002 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005003 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5004 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005005
5006 int client_ret = SSL_do_handshake(client.get());
5007 int client_err = SSL_get_error(client.get(), client_ret);
5008 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5009
5010 int server_ret = SSL_do_handshake(server.get());
5011 int server_err = SSL_get_error(server.get(), server_ret);
5012 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5013
5014 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005015 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005016 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005017 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005018
5019 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5020
5021 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5022
5023 uint8_t byte = 42;
5024 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5025 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5026 EXPECT_EQ(42, byte);
5027
5028 byte = 43;
5029 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5030 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5031 EXPECT_EQ(43, byte);
5032}
5033
Adam Langley826ce152018-08-03 10:31:21 -07005034static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5035 std::string ret = "{";
5036
5037 for (uint16_t v : sigalgs) {
5038 if (ret.size() > 1) {
5039 ret += ", ";
5040 }
5041
5042 char buf[8];
5043 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5044 buf[sizeof(buf)-1] = 0;
5045 ret += std::string(buf);
5046 }
5047
5048 ret += "}";
5049 return ret;
5050}
5051
5052void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5053 Span<const uint16_t> actual) {
5054 bool matches = false;
5055 if (expected.size() == actual.size()) {
5056 matches = true;
5057
5058 for (size_t i = 0; i < expected.size(); i++) {
5059 if (expected[i] != actual[i]) {
5060 matches = false;
5061 break;
5062 }
5063 }
5064 }
5065
5066 if (!matches) {
5067 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5068 << " got: " << SigAlgsToString(actual);
5069 }
5070}
5071
5072TEST(SSLTest, SigAlgs) {
5073 static const struct {
5074 std::vector<int> input;
5075 bool ok;
5076 std::vector<uint16_t> expected;
5077 } kTests[] = {
5078 {{}, true, {}},
5079 {{1}, false, {}},
5080 {{1, 2, 3}, false, {}},
5081 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5082 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5083
5084 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5085 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5086 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5087 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5088 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5089 true,
5090 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5091 };
5092
5093 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5094
5095 unsigned n = 1;
5096 for (const auto &test : kTests) {
5097 SCOPED_TRACE(n++);
5098
5099 const bool ok =
5100 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5101 EXPECT_EQ(ok, test.ok);
5102
5103 if (!ok) {
5104 ERR_clear_error();
5105 }
5106
5107 if (!test.ok) {
5108 continue;
5109 }
5110
5111 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5112 }
5113}
5114
5115TEST(SSLTest, SigAlgsList) {
5116 static const struct {
5117 const char *input;
5118 bool ok;
5119 std::vector<uint16_t> expected;
5120 } kTests[] = {
5121 {"", false, {}},
5122 {":", false, {}},
5123 {"+", false, {}},
5124 {"RSA", false, {}},
5125 {"RSA+", false, {}},
5126 {"RSA+SHA256:", false, {}},
5127 {":RSA+SHA256:", false, {}},
5128 {":RSA+SHA256+:", false, {}},
5129 {"!", false, {}},
5130 {"\x01", false, {}},
5131 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5132 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5133
5134 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5135 {"RSA+SHA256:ed25519",
5136 true,
5137 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5138 {"ECDSA+SHA256:RSA+SHA512",
5139 true,
5140 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5141 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5142 true,
5143 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5144 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5145 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5146 };
5147
5148 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5149
5150 unsigned n = 1;
5151 for (const auto &test : kTests) {
5152 SCOPED_TRACE(n++);
5153
5154 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5155 EXPECT_EQ(ok, test.ok);
5156
5157 if (!ok) {
5158 if (test.ok) {
5159 ERR_print_errors_fp(stderr);
5160 }
5161 ERR_clear_error();
5162 }
5163
5164 if (!test.ok) {
5165 continue;
5166 }
5167
5168 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5169 }
5170}
5171
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005172TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5173 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5174 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5175
5176 // handoff is a handoff message that has been artificially modified to pretend
5177 // that only cipher 0x0A is supported. When it is applied to |server|, all
5178 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005179 //
5180 // To make a new one of these, try sticking this in the |Handoff| test above:
5181 //
5182 // hexdump(stderr, "", handoff.data(), handoff.size());
5183 // sed -e 's/\(..\)/0x\1, /g'
5184 //
5185 // and modify serialize_features() to emit only cipher 0x0A.
5186
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005187 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005188 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5189 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5190 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5191 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5192 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005193 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5194 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005195 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5196 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5197 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5198 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5199 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
5200 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5201 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005202 };
5203
5204 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5205 ASSERT_TRUE(
5206 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5207 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5208}
5209
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005210TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5211 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5212 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5213
5214 // handoff is a handoff message that has been artificially modified to pretend
5215 // that only one curve is supported. When it is applied to |server|, all
5216 // curves but that one should be removed.
5217 //
5218 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5219 // these.
5220 uint8_t handoff[] = {
5221 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5222 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5223 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5224 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5225 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5226 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5227 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5228 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5229 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5230 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5231 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5232 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5233 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5234 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5235 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5236 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5237 0x02, 0x00, 0x17,
5238 };
5239
5240 // The zero length means that the default list of groups is used.
5241 EXPECT_EQ(0u, server->config->supported_group_list.size());
5242 ASSERT_TRUE(
5243 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5244 EXPECT_EQ(1u, server->config->supported_group_list.size());
5245}
5246
Adam Langleyba9ad662018-12-17 13:59:38 -08005247TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5248 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5249 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005250 bssl::UniquePtr<SSL_CTX> server_ctx(
5251 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005252 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5253 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005254
5255 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5256 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5257 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5258
5259 bssl::UniquePtr<SSL> client, server;
5260 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5261 server_ctx.get()));
5262
5263 BIO *client_wbio = SSL_get_wbio(client.get());
5264 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5265 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5266 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5267 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5268 EXPECT_NE(0u, BIO_wpending(client_wbio));
5269}
5270
David Benjamin5869eb32018-07-17 00:59:45 -04005271TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5272 // Configure the server to request client certificates.
5273 SSL_CTX_set_custom_verify(
5274 server_ctx_.get(), SSL_VERIFY_PEER,
5275 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5276
5277 // Configure the client to reject the server certificate.
5278 SSL_CTX_set_custom_verify(
5279 client_ctx_.get(), SSL_VERIFY_PEER,
5280 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5281
5282 // cert_cb should not be called. Verification should fail first.
5283 SSL_CTX_set_cert_cb(client_ctx_.get(),
5284 [](SSL *ssl, void *arg) {
5285 ADD_FAILURE() << "cert_cb unexpectedly called";
5286 return 0;
5287 },
5288 nullptr);
5289
5290 bssl::UniquePtr<SSL> client, server;
5291 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5292 server_ctx_.get()));
5293}
5294
David Benjamin492c9aa2018-08-31 16:35:22 -05005295// Test that ticket-based sessions on the client get fake session IDs.
5296TEST_P(SSLVersionTest, FakeIDsForTickets) {
5297 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5298 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5299
5300 bssl::UniquePtr<SSL_SESSION> session =
5301 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5302 ASSERT_TRUE(session);
5303
5304 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5305 unsigned session_id_length;
5306 SSL_SESSION_get_id(session.get(), &session_id_length);
5307 EXPECT_NE(session_id_length, 0u);
5308}
5309
David Benjamin6c04bd12018-07-19 18:13:09 -04005310// These tests test multi-threaded behavior. They are intended to run with
5311// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005312#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005313TEST_P(SSLVersionTest, SessionCacheThreads) {
5314 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5315 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5316 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5317
5318 if (version() == TLS1_3_VERSION) {
5319 // Our TLS 1.3 implementation does not support stateful resumption.
5320 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5321 return;
5322 }
5323
5324 // Establish two client sessions to test with.
5325 bssl::UniquePtr<SSL_SESSION> session1 =
5326 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5327 ASSERT_TRUE(session1);
5328 bssl::UniquePtr<SSL_SESSION> session2 =
5329 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5330 ASSERT_TRUE(session2);
5331
5332 auto connect_with_session = [&](SSL_SESSION *session) {
5333 ClientConfig config;
5334 config.session = session;
5335 UniquePtr<SSL> client, server;
5336 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5337 server_ctx_.get(), config));
5338 };
5339
5340 // Resume sessions in parallel with establishing new ones.
5341 {
5342 std::vector<std::thread> threads;
5343 threads.emplace_back([&] { connect_with_session(nullptr); });
5344 threads.emplace_back([&] { connect_with_session(nullptr); });
5345 threads.emplace_back([&] { connect_with_session(session1.get()); });
5346 threads.emplace_back([&] { connect_with_session(session1.get()); });
5347 threads.emplace_back([&] { connect_with_session(session2.get()); });
5348 threads.emplace_back([&] { connect_with_session(session2.get()); });
5349 for (auto &thread : threads) {
5350 thread.join();
5351 }
5352 }
5353
5354 // Hit the maximum session cache size across multiple threads
5355 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5356 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5357 {
5358 std::vector<std::thread> threads;
5359 for (int i = 0; i < 4; i++) {
5360 threads.emplace_back([&]() {
5361 connect_with_session(nullptr);
5362 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5363 });
5364 }
5365 for (auto &thread : threads) {
5366 thread.join();
5367 }
5368 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5369 }
5370}
5371
5372TEST_P(SSLVersionTest, SessionTicketThreads) {
5373 for (bool renew_ticket : {false, true}) {
5374 SCOPED_TRACE(renew_ticket);
5375 ResetContexts();
5376 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5377 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5378 if (renew_ticket) {
5379 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5380 }
5381
5382 // Establish two client sessions to test with.
5383 bssl::UniquePtr<SSL_SESSION> session1 =
5384 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5385 ASSERT_TRUE(session1);
5386 bssl::UniquePtr<SSL_SESSION> session2 =
5387 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5388 ASSERT_TRUE(session2);
5389
5390 auto connect_with_session = [&](SSL_SESSION *session) {
5391 ClientConfig config;
5392 config.session = session;
5393 UniquePtr<SSL> client, server;
5394 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5395 server_ctx_.get(), config));
5396 };
5397
5398 // Resume sessions in parallel with establishing new ones.
5399 {
5400 std::vector<std::thread> threads;
5401 threads.emplace_back([&] { connect_with_session(nullptr); });
5402 threads.emplace_back([&] { connect_with_session(nullptr); });
5403 threads.emplace_back([&] { connect_with_session(session1.get()); });
5404 threads.emplace_back([&] { connect_with_session(session1.get()); });
5405 threads.emplace_back([&] { connect_with_session(session2.get()); });
5406 threads.emplace_back([&] { connect_with_session(session2.get()); });
5407 for (auto &thread : threads) {
5408 thread.join();
5409 }
5410 }
5411 }
5412}
5413
5414// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5415TEST(SSLTest, GetCertificateThreads) {
5416 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5417 ASSERT_TRUE(ctx);
5418 bssl::UniquePtr<X509> cert = GetTestCertificate();
5419 ASSERT_TRUE(cert);
5420 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5421
5422 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5423 // threads concurrently. It originally was an immutable operation. Now we
5424 // implement it with a thread-safe cache, so it is worth testing.
5425 X509 *cert2_thread;
5426 std::thread thread(
5427 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5428 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5429 thread.join();
5430
5431 EXPECT_EQ(cert2, cert2_thread);
5432 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5433}
David Benjamin4cce9552018-12-13 12:20:54 -06005434
5435// Functions which access properties on the negotiated session are thread-safe
5436// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5437// performing stateful resumption will share an underlying SSL_SESSION object,
5438// potentially across threads.
5439TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5440 if (version() == TLS1_3_VERSION) {
5441 // Our TLS 1.3 implementation does not support stateful resumption.
5442 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5443 return;
5444 }
5445
5446 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5447 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5448 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5449
5450 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5451 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5452
5453 // Configure mutual authentication, so we have more session state.
5454 SSL_CTX_set_custom_verify(
5455 client_ctx_.get(), SSL_VERIFY_PEER,
5456 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5457 SSL_CTX_set_custom_verify(
5458 server_ctx_.get(), SSL_VERIFY_PEER,
5459 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5460
5461 // Establish a client session to test with.
5462 bssl::UniquePtr<SSL_SESSION> session =
5463 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5464 ASSERT_TRUE(session);
5465
5466 // Resume with it twice.
5467 UniquePtr<SSL> ssls[4];
5468 ClientConfig config;
5469 config.session = session.get();
5470 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5471 server_ctx_.get(), config));
5472 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5473 server_ctx_.get(), config));
5474
5475 // Read properties in parallel.
5476 auto read_properties = [](const SSL *ssl) {
5477 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5478 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5479 EXPECT_TRUE(peer);
5480 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5481 EXPECT_TRUE(SSL_get_curve_id(ssl));
5482 };
5483
5484 std::vector<std::thread> threads;
5485 for (const auto &ssl_ptr : ssls) {
5486 const SSL *ssl = ssl_ptr.get();
5487 threads.emplace_back([=] { read_properties(ssl); });
5488 }
5489 for (auto &thread : threads) {
5490 thread.join();
5491 }
5492}
David Benjamina486c6c2019-03-28 18:32:38 -05005493#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005494
Steven Valdezc8e0f902018-07-14 11:23:01 -04005495constexpr size_t kNumQUICLevels = 4;
5496static_assert(ssl_encryption_initial < kNumQUICLevels,
5497 "kNumQUICLevels is wrong");
5498static_assert(ssl_encryption_early_data < kNumQUICLevels,
5499 "kNumQUICLevels is wrong");
5500static_assert(ssl_encryption_handshake < kNumQUICLevels,
5501 "kNumQUICLevels is wrong");
5502static_assert(ssl_encryption_application < kNumQUICLevels,
5503 "kNumQUICLevels is wrong");
5504
David Benjamin1e859052020-02-09 16:04:58 -05005505const char *LevelToString(ssl_encryption_level_t level) {
5506 switch (level) {
5507 case ssl_encryption_initial:
5508 return "initial";
5509 case ssl_encryption_early_data:
5510 return "early data";
5511 case ssl_encryption_handshake:
5512 return "handshake";
5513 case ssl_encryption_application:
5514 return "application";
5515 }
5516 return "<unknown>";
5517}
5518
Steven Valdezc8e0f902018-07-14 11:23:01 -04005519class MockQUICTransport {
5520 public:
David Benjamind6343572019-08-15 17:29:02 -04005521 enum class Role { kClient, kServer };
5522
5523 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005524 // The caller is expected to configure initial secrets.
5525 levels_[ssl_encryption_initial].write_secret = {1};
5526 levels_[ssl_encryption_initial].read_secret = {1};
5527 }
5528
5529 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5530
5531 bool has_alert() const { return has_alert_; }
5532 ssl_encryption_level_t alert_level() const { return alert_level_; }
5533 uint8_t alert() const { return alert_; }
5534
5535 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5536 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005537 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5538 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005539 }
5540
David Benjamin1e859052020-02-09 16:04:58 -05005541 bool HasReadSecret(ssl_encryption_level_t level) const {
5542 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005543 }
5544
David Benjamin1e859052020-02-09 16:04:58 -05005545 bool HasWriteSecret(ssl_encryption_level_t level) const {
5546 return !levels_[level].write_secret.empty();
5547 }
5548
David Benjamin5298ef92020-03-13 12:17:30 -04005549 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5550
David Benjamin1e859052020-02-09 16:04:58 -05005551 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5552 Span<const uint8_t> secret) {
5553 if (HasReadSecret(level)) {
5554 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5555 return false;
5556 }
5557
5558 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5559 ADD_FAILURE() << "Unexpected early data read secret";
5560 return false;
5561 }
5562
5563 ssl_encryption_level_t ack_level =
5564 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5565 if (!HasWriteSecret(ack_level)) {
5566 ADD_FAILURE() << LevelToString(level)
5567 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005568 return false;
5569 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005570
5571 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005572 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005573 return false;
5574 }
5575
David Benjamin1e859052020-02-09 16:04:58 -05005576 if (level != ssl_encryption_early_data &&
5577 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5578 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005579 return false;
5580 }
David Benjamind6343572019-08-15 17:29:02 -04005581
David Benjamin1e859052020-02-09 16:04:58 -05005582 levels_[level].read_secret.assign(secret.begin(), secret.end());
5583 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5584 return true;
5585 }
5586
5587 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5588 Span<const uint8_t> secret) {
5589 if (HasWriteSecret(level)) {
5590 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005591 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005592 }
David Benjamind6343572019-08-15 17:29:02 -04005593
David Benjamin1e859052020-02-09 16:04:58 -05005594 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5595 ADD_FAILURE() << "Unexpected early data write secret";
5596 return false;
5597 }
5598
5599 if (cipher == nullptr) {
5600 ADD_FAILURE() << "Unexpected null cipher";
5601 return false;
5602 }
5603
5604 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005605 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005606 return true;
5607 }
5608
5609 bool WriteHandshakeData(ssl_encryption_level_t level,
5610 Span<const uint8_t> data) {
5611 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005612 ADD_FAILURE() << LevelToString(level)
5613 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005614 return false;
5615 }
David Benjamin5298ef92020-03-13 12:17:30 -04005616
5617 // Although the levels are conceptually separate, BoringSSL finishes writing
5618 // data from a previous level before installing keys for the next level.
5619 if (!allow_out_of_order_writes_) {
5620 switch (level) {
5621 case ssl_encryption_early_data:
5622 ADD_FAILURE() << "unexpected handshake data at early data level";
5623 return false;
5624 case ssl_encryption_initial:
5625 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5626 ADD_FAILURE()
5627 << LevelToString(level)
5628 << " handshake data written after handshake keys installed";
5629 return false;
5630 }
5631 OPENSSL_FALLTHROUGH;
5632 case ssl_encryption_handshake:
5633 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5634 ADD_FAILURE()
5635 << LevelToString(level)
5636 << " handshake data written after application keys installed";
5637 return false;
5638 }
5639 OPENSSL_FALLTHROUGH;
5640 case ssl_encryption_application:
5641 break;
5642 }
5643 }
5644
Steven Valdezc8e0f902018-07-14 11:23:01 -04005645 levels_[level].write_data.insert(levels_[level].write_data.end(),
5646 data.begin(), data.end());
5647 return true;
5648 }
5649
5650 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5651 if (has_alert_) {
5652 ADD_FAILURE() << "duplicate alert sent";
5653 return false;
5654 }
5655
5656 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005657 ADD_FAILURE() << LevelToString(level)
5658 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005659 return false;
5660 }
5661
5662 has_alert_ = true;
5663 alert_level_ = level;
5664 alert_ = alert_value;
5665 return true;
5666 }
5667
5668 bool ReadHandshakeData(std::vector<uint8_t> *out,
5669 ssl_encryption_level_t level,
5670 size_t num = std::numeric_limits<size_t>::max()) {
5671 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005672 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005673 return false;
5674 }
5675 // The peer may not have configured any keys yet.
5676 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005677 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005678 return true;
5679 }
5680 // Check the peer computed the same key.
5681 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005682 ADD_FAILURE() << "peer write key does not match read key in level "
5683 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005684 return false;
5685 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005686 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005687 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005688 return false;
5689 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005690 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5691 num = std::min(num, peer_data->size());
5692 out->assign(peer_data->begin(), peer_data->begin() + num);
5693 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5694 return true;
5695 }
5696
5697 private:
David Benjamind6343572019-08-15 17:29:02 -04005698 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005699 MockQUICTransport *peer_ = nullptr;
5700
David Benjamin5298ef92020-03-13 12:17:30 -04005701 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005702 bool has_alert_ = false;
5703 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5704 uint8_t alert_ = 0;
5705
5706 struct Level {
5707 std::vector<uint8_t> write_data;
5708 std::vector<uint8_t> write_secret;
5709 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005710 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005711 };
5712 Level levels_[kNumQUICLevels];
5713};
5714
5715class MockQUICTransportPair {
5716 public:
David Benjamind6343572019-08-15 17:29:02 -04005717 MockQUICTransportPair()
5718 : client_(MockQUICTransport::Role::kClient),
5719 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005720 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005721 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005722 }
5723
5724 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005725 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005726 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005727 }
5728
5729 MockQUICTransport *client() { return &client_; }
5730 MockQUICTransport *server() { return &server_; }
5731
5732 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005733 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5734 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5735 return client_.PeerSecretsMatch(level) &&
5736 client_.HasWriteSecret(level) &&
5737 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005738 }
5739
5740 private:
5741 MockQUICTransport client_;
5742 MockQUICTransport server_;
5743};
5744
5745class QUICMethodTest : public testing::Test {
5746 protected:
5747 void SetUp() override {
5748 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005749 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005750 ASSERT_TRUE(client_ctx_);
5751 ASSERT_TRUE(server_ctx_);
5752
Steven Valdezc8e0f902018-07-14 11:23:01 -04005753 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5754 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5755 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5756 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005757
5758 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5759 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5760 sizeof(kALPNProtos)),
5761 0);
5762 SSL_CTX_set_alpn_select_cb(
5763 server_ctx_.get(),
5764 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5765 unsigned in_len, void *arg) -> int {
5766 return SSL_select_next_proto(
5767 const_cast<uint8_t **>(out), out_len, in, in_len,
5768 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5769 ? SSL_TLSEXT_ERR_OK
5770 : SSL_TLSEXT_ERR_NOACK;
5771 },
5772 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005773 }
5774
5775 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5776 return ex_data_.Get(ssl);
5777 }
5778
5779 static bool ProvideHandshakeData(
5780 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5781 MockQUICTransport *transport = TransportFromSSL(ssl);
5782 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5783 std::vector<uint8_t> data;
5784 return transport->ReadHandshakeData(&data, level, num) &&
5785 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5786 }
5787
David Benjamin5298ef92020-03-13 12:17:30 -04005788 void AllowOutOfOrderWrites() {
5789 allow_out_of_order_writes_ = true;
5790 }
5791
Steven Valdezc8e0f902018-07-14 11:23:01 -04005792 bool CreateClientAndServer() {
5793 client_.reset(SSL_new(client_ctx_.get()));
5794 server_.reset(SSL_new(server_ctx_.get()));
5795 if (!client_ || !server_) {
5796 return false;
5797 }
5798
5799 SSL_set_connect_state(client_.get());
5800 SSL_set_accept_state(server_.get());
5801
David Benjamind6343572019-08-15 17:29:02 -04005802 transport_.reset(new MockQUICTransportPair);
5803 ex_data_.Set(client_.get(), transport_->client());
5804 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005805 if (allow_out_of_order_writes_) {
5806 transport_->client()->AllowOutOfOrderWrites();
5807 transport_->server()->AllowOutOfOrderWrites();
5808 }
Nick Harper7c522992020-04-30 14:15:49 -07005809 static const uint8_t client_transport_params[] = {0};
5810 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5811 sizeof(client_transport_params)) ||
5812 !SSL_set_quic_transport_params(server_.get(),
5813 server_transport_params_.data(),
5814 server_transport_params_.size()) ||
5815 !SSL_set_quic_early_data_context(
5816 server_.get(), server_quic_early_data_context_.data(),
5817 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005818 return false;
5819 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005820 return true;
5821 }
5822
Nick Harper72cff812020-03-26 18:06:16 -07005823 enum class ExpectedError {
5824 kNoError,
5825 kClientError,
5826 kServerError,
5827 };
5828
David Benjamind6343572019-08-15 17:29:02 -04005829 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5830 // |server_| until each completes once. It returns true on success and false
5831 // on failure.
5832 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005833 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5834 }
5835
5836 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5837 // once. If |expect_client_error| is true, it will return true only if the
5838 // client handshake failed. Otherwise, it returns true if both handshakes
5839 // succeed and false otherwise.
5840 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005841 bool client_done = false, server_done = false;
5842 while (!client_done || !server_done) {
5843 if (!client_done) {
5844 if (!ProvideHandshakeData(client_.get())) {
5845 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5846 return false;
5847 }
5848 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005849 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005850 if (client_ret == 1) {
5851 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005852 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005853 if (expected_error == ExpectedError::kClientError) {
5854 return true;
5855 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005856 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5857 << client_err;
5858 return false;
David Benjamind6343572019-08-15 17:29:02 -04005859 }
5860 }
5861
5862 if (!server_done) {
5863 if (!ProvideHandshakeData(server_.get())) {
5864 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5865 return false;
5866 }
5867 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005868 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005869 if (server_ret == 1) {
5870 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005871 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005872 if (expected_error == ExpectedError::kServerError) {
5873 return true;
5874 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005875 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5876 << server_err;
5877 return false;
David Benjamind6343572019-08-15 17:29:02 -04005878 }
5879 }
5880 }
Nick Harper72cff812020-03-26 18:06:16 -07005881 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005882 }
5883
5884 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5885 g_last_session = nullptr;
5886 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5887 if (!CreateClientAndServer() ||
5888 !CompleteHandshakesForQUIC()) {
5889 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005890 }
5891
David Benjamind6343572019-08-15 17:29:02 -04005892 // The server sent NewSessionTicket messages in the handshake.
5893 if (!ProvideHandshakeData(client_.get()) ||
5894 !SSL_process_quic_post_handshake(client_.get())) {
5895 return nullptr;
5896 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005897
David Benjamind6343572019-08-15 17:29:02 -04005898 return std::move(g_last_session);
5899 }
5900
5901 void ExpectHandshakeSuccess() {
5902 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5903 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5904 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5905 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5906 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5907 EXPECT_FALSE(transport_->client()->has_alert());
5908 EXPECT_FALSE(transport_->server()->has_alert());
5909
5910 // SSL_do_handshake is now idempotent.
5911 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5912 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005913 }
5914
David Benjamin1e859052020-02-09 16:04:58 -05005915 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5916 // the test.
5917 SSL_QUIC_METHOD DefaultQUICMethod() {
5918 return SSL_QUIC_METHOD{
5919 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5920 FlushFlightCallback, SendAlertCallback,
5921 };
5922 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005923
David Benjamin1e859052020-02-09 16:04:58 -05005924 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5925 const SSL_CIPHER *cipher,
5926 const uint8_t *secret, size_t secret_len) {
5927 return TransportFromSSL(ssl)->SetReadSecret(
5928 level, cipher, MakeConstSpan(secret, secret_len));
5929 }
5930
5931 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5932 const SSL_CIPHER *cipher,
5933 const uint8_t *secret, size_t secret_len) {
5934 return TransportFromSSL(ssl)->SetWriteSecret(
5935 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005936 }
5937
David Benjamincc9d9352018-10-30 19:45:22 -05005938 static int AddHandshakeDataCallback(SSL *ssl,
5939 enum ssl_encryption_level_t level,
5940 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005941 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5942 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5943 MakeConstSpan(data, len));
5944 }
5945
5946 static int FlushFlightCallback(SSL *ssl) { return 1; }
5947
5948 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5949 uint8_t alert) {
5950 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5951 return TransportFromSSL(ssl)->SendAlert(level, alert);
5952 }
5953
5954 bssl::UniquePtr<SSL_CTX> client_ctx_;
5955 bssl::UniquePtr<SSL_CTX> server_ctx_;
5956
5957 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005958 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005959
5960 bssl::UniquePtr<SSL> client_;
5961 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005962
Nick Harper7c522992020-04-30 14:15:49 -07005963 std::vector<uint8_t> server_transport_params_ = {1};
5964 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5965
David Benjamin5298ef92020-03-13 12:17:30 -04005966 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005967};
5968
5969UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5970
David Benjaminfd863b62019-07-25 13:51:32 -04005971// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005972TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005973 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005974
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005975 g_last_session = nullptr;
5976
5977 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5978 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005979 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5980 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005981
Steven Valdezc8e0f902018-07-14 11:23:01 -04005982 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005983 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005984
David Benjamind6343572019-08-15 17:29:02 -04005985 ExpectHandshakeSuccess();
5986 EXPECT_FALSE(SSL_session_reused(client_.get()));
5987 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005988
5989 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005990 EXPECT_FALSE(g_last_session);
5991 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5992 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5993 EXPECT_TRUE(g_last_session);
5994
5995 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005996 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005997 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5998 SSL_set_session(client_.get(), session.get());
5999
David Benjamind6343572019-08-15 17:29:02 -04006000 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006001
David Benjamind6343572019-08-15 17:29:02 -04006002 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006003 EXPECT_TRUE(SSL_session_reused(client_.get()));
6004 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006005}
6006
David Benjaminfd863b62019-07-25 13:51:32 -04006007// Test that HelloRetryRequest in QUIC works.
6008TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006009 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006010
6011 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6012 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6013
6014 // BoringSSL predicts the most preferred curve, so using different preferences
6015 // will trigger HelloRetryRequest.
6016 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6017 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
6018 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6019 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6020 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
6021 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6022
6023 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006024 ASSERT_TRUE(CompleteHandshakesForQUIC());
6025 ExpectHandshakeSuccess();
6026}
David Benjaminfd863b62019-07-25 13:51:32 -04006027
Nick Harpere32549e2020-05-06 14:27:11 -07006028// Test that the client does not send a legacy_session_id in the ClientHello.
6029TEST_F(QUICMethodTest, NoLegacySessionId) {
6030 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6031
6032 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6033 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6034 // Check that the session ID length is 0 in an early callback.
6035 SSL_CTX_set_select_certificate_cb(
6036 server_ctx_.get(),
6037 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6038 EXPECT_EQ(client_hello->session_id_len, 0u);
6039 return ssl_select_cert_success;
6040 });
6041
6042 ASSERT_TRUE(CreateClientAndServer());
6043 ASSERT_TRUE(CompleteHandshakesForQUIC());
6044
6045 ExpectHandshakeSuccess();
6046}
6047
David Benjamin1e859052020-02-09 16:04:58 -05006048// Test that, even in a 1-RTT handshake, the server installs keys at the right
6049// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6050TEST_F(QUICMethodTest, HalfRTTKeys) {
6051 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6052
6053 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6054 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6055 ASSERT_TRUE(CreateClientAndServer());
6056
6057 // The client sends ClientHello.
6058 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6059 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6060
6061 // The server reads ClientHello and sends ServerHello..Finished.
6062 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6063 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6064 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6065
6066 // At this point, the server has half-RTT write keys, but it cannot access
6067 // 1-RTT read keys until client Finished.
6068 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6069 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6070
6071 // Finish up the client and server handshakes.
6072 ASSERT_TRUE(CompleteHandshakesForQUIC());
6073
6074 // Both sides can now exchange 1-RTT data.
6075 ExpectHandshakeSuccess();
6076}
6077
David Benjamind6343572019-08-15 17:29:02 -04006078TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006079 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006080
6081 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6082 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6083 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6084 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6085 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6086
6087 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6088 ASSERT_TRUE(session);
6089
6090 ASSERT_TRUE(CreateClientAndServer());
6091 SSL_set_session(client_.get(), session.get());
6092
6093 // The client handshake should return immediately into the early data state.
6094 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6095 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6096 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006097 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006098
6099 // The server will consume the ClientHello and also enter the early data
6100 // state.
6101 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6102 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6103 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6104 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006105 // At this point, the server has half-RTT write keys, but it cannot access
6106 // 1-RTT read keys until client Finished.
6107 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6108 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006109
6110 // Finish up the client and server handshakes.
6111 ASSERT_TRUE(CompleteHandshakesForQUIC());
6112
6113 // Both sides can now exchange 1-RTT data.
6114 ExpectHandshakeSuccess();
6115 EXPECT_TRUE(SSL_session_reused(client_.get()));
6116 EXPECT_TRUE(SSL_session_reused(server_.get()));
6117 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6118 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6119 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6120 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006121
6122 // Finish handling post-handshake messages after the first 0-RTT resumption.
6123 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6124 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6125
6126 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6127 // accepted again.
6128 ASSERT_TRUE(CreateClientAndServer());
6129 SSL_set_session(client_.get(), g_last_session.get());
6130
6131 // The client handshake should return immediately into the early data state.
6132 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6133 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6134 // The transport should have keys for sending 0-RTT data.
6135 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6136
6137 // The server will consume the ClientHello and also enter the early data
6138 // state.
6139 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6140 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6141 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6142 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6143 // At this point, the server has half-RTT write keys, but it cannot access
6144 // 1-RTT read keys until client Finished.
6145 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6146 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6147
6148 // Finish up the client and server handshakes.
6149 ASSERT_TRUE(CompleteHandshakesForQUIC());
6150
6151 // Both sides can now exchange 1-RTT data.
6152 ExpectHandshakeSuccess();
6153 EXPECT_TRUE(SSL_session_reused(client_.get()));
6154 EXPECT_TRUE(SSL_session_reused(server_.get()));
6155 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6156 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6157 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6158 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6159 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6160 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006161}
6162
Nick Harper7c522992020-04-30 14:15:49 -07006163TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6164 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6165
6166 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6167 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6168 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6169 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6170 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6171
6172
6173 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6174 ASSERT_TRUE(session);
6175
Nick Harper85194322020-05-20 16:59:29 -07006176 ASSERT_TRUE(CreateClientAndServer());
6177 static const uint8_t new_context[] = {4};
6178 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6179 sizeof(new_context)));
6180 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006181
Nick Harper85194322020-05-20 16:59:29 -07006182 // The client handshake should return immediately into the early data
6183 // state.
6184 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6185 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6186 // The transport should have keys for sending 0-RTT data.
6187 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006188
Nick Harper85194322020-05-20 16:59:29 -07006189 // The server will consume the ClientHello, but it will not accept 0-RTT.
6190 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6191 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6192 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6193 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6194 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006195
Nick Harper85194322020-05-20 16:59:29 -07006196 // The client consumes the server response and signals 0-RTT rejection.
6197 for (;;) {
6198 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6199 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6200 int err = SSL_get_error(client_.get(), -1);
6201 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6202 break;
Nick Harper7c522992020-04-30 14:15:49 -07006203 }
Nick Harper85194322020-05-20 16:59:29 -07006204 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006205 }
Nick Harper85194322020-05-20 16:59:29 -07006206
6207 // As in TLS over TCP, 0-RTT rejection is sticky.
6208 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6209 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6210
6211 // Finish up the client and server handshakes.
6212 SSL_reset_early_data_reject(client_.get());
6213 ASSERT_TRUE(CompleteHandshakesForQUIC());
6214
6215 // Both sides can now exchange 1-RTT data.
6216 ExpectHandshakeSuccess();
6217 EXPECT_TRUE(SSL_session_reused(client_.get()));
6218 EXPECT_TRUE(SSL_session_reused(server_.get()));
6219 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6220 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6221 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6222 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6223}
6224
6225TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6226 server_quic_early_data_context_ = {};
6227 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6228
6229 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6230 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6231 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6232 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6233 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6234
6235 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6236 ASSERT_TRUE(session);
6237 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006238}
6239
David Benjamind6343572019-08-15 17:29:02 -04006240TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006241 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006242
6243 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6244 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6245 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6246 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6247 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6248
6249 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6250 ASSERT_TRUE(session);
6251
6252 for (bool reject_hrr : {false, true}) {
6253 SCOPED_TRACE(reject_hrr);
6254
6255 ASSERT_TRUE(CreateClientAndServer());
6256 if (reject_hrr) {
6257 // Configure the server to prefer P-256, which will reject 0-RTT via
6258 // HelloRetryRequest.
6259 int p256 = NID_X9_62_prime256v1;
6260 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6261 } else {
6262 // Disable 0-RTT on the server, so it will reject it.
6263 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006264 }
David Benjamind6343572019-08-15 17:29:02 -04006265 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006266
David Benjamind6343572019-08-15 17:29:02 -04006267 // The client handshake should return immediately into the early data state.
6268 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6269 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6270 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006271 EXPECT_TRUE(
6272 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006273
6274 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006275 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006276 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6277 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6278 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006279 EXPECT_FALSE(
6280 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006281
6282 // The client consumes the server response and signals 0-RTT rejection.
6283 for (;;) {
6284 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6285 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6286 int err = SSL_get_error(client_.get(), -1);
6287 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6288 break;
6289 }
6290 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006291 }
6292
David Benjamind6343572019-08-15 17:29:02 -04006293 // As in TLS over TCP, 0-RTT rejection is sticky.
6294 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6295 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6296
6297 // Finish up the client and server handshakes.
6298 SSL_reset_early_data_reject(client_.get());
6299 ASSERT_TRUE(CompleteHandshakesForQUIC());
6300
6301 // Both sides can now exchange 1-RTT data.
6302 ExpectHandshakeSuccess();
6303 EXPECT_TRUE(SSL_session_reused(client_.get()));
6304 EXPECT_TRUE(SSL_session_reused(server_.get()));
6305 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6306 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6307 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6308 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006309 }
David Benjaminfd863b62019-07-25 13:51:32 -04006310}
6311
David Benjaminee0716f2019-11-19 14:16:28 +08006312TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006313 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006314
6315 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6316 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6317 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6318 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6319 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6320 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6321
6322 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6323 ASSERT_TRUE(session);
6324
6325 ASSERT_TRUE(CreateClientAndServer());
6326 SSL_set_session(client_.get(), session.get());
6327
6328 // Configure the certificate (re)verification to never complete. The client
6329 // handshake should pause.
6330 SSL_set_custom_verify(
6331 client_.get(), SSL_VERIFY_PEER,
6332 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6333 return ssl_verify_retry;
6334 });
6335 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6336 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6337 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6338
6339 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006340 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006341
6342 // After the verification completes, the handshake progresses to the 0-RTT
6343 // point and releases keys.
6344 SSL_set_custom_verify(
6345 client_.get(), SSL_VERIFY_PEER,
6346 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6347 return ssl_verify_ok;
6348 });
6349 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6350 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006351 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006352}
6353
Steven Valdezc8e0f902018-07-14 11:23:01 -04006354// Test only releasing data to QUIC one byte at a time on request, to maximize
6355// state machine pauses. Additionally, test that existing asynchronous callbacks
6356// still work.
6357TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006358 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006359
6360 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6361 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6362 ASSERT_TRUE(CreateClientAndServer());
6363
6364 // Install an asynchronous certificate callback.
6365 bool cert_cb_ok = false;
6366 SSL_set_cert_cb(server_.get(),
6367 [](SSL *, void *arg) -> int {
6368 return *static_cast<bool *>(arg) ? 1 : -1;
6369 },
6370 &cert_cb_ok);
6371
6372 for (;;) {
6373 int client_ret = SSL_do_handshake(client_.get());
6374 if (client_ret != 1) {
6375 ASSERT_EQ(client_ret, -1);
6376 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6377 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6378 }
6379
6380 int server_ret = SSL_do_handshake(server_.get());
6381 if (server_ret != 1) {
6382 ASSERT_EQ(server_ret, -1);
6383 int ssl_err = SSL_get_error(server_.get(), server_ret);
6384 switch (ssl_err) {
6385 case SSL_ERROR_WANT_READ:
6386 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6387 break;
6388 case SSL_ERROR_WANT_X509_LOOKUP:
6389 ASSERT_FALSE(cert_cb_ok);
6390 cert_cb_ok = true;
6391 break;
6392 default:
6393 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6394 }
6395 }
6396
6397 if (client_ret == 1 && server_ret == 1) {
6398 break;
6399 }
6400 }
6401
David Benjamind6343572019-08-15 17:29:02 -04006402 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006403}
6404
6405// Test buffering write data until explicit flushes.
6406TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006407 AllowOutOfOrderWrites();
6408
Steven Valdezc8e0f902018-07-14 11:23:01 -04006409 struct BufferedFlight {
6410 std::vector<uint8_t> data[kNumQUICLevels];
6411 };
6412 static UnownedSSLExData<BufferedFlight> buffered_flights;
6413
David Benjamincc9d9352018-10-30 19:45:22 -05006414 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6415 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006416 BufferedFlight *flight = buffered_flights.Get(ssl);
6417 flight->data[level].insert(flight->data[level].end(), data, data + len);
6418 return 1;
6419 };
6420
6421 auto flush_flight = [](SSL *ssl) -> int {
6422 BufferedFlight *flight = buffered_flights.Get(ssl);
6423 for (size_t level = 0; level < kNumQUICLevels; level++) {
6424 if (!flight->data[level].empty()) {
6425 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6426 static_cast<ssl_encryption_level_t>(level),
6427 flight->data[level])) {
6428 return 0;
6429 }
6430 flight->data[level].clear();
6431 }
6432 }
6433 return 1;
6434 };
6435
David Benjamin1e859052020-02-09 16:04:58 -05006436 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6437 quic_method.add_handshake_data = add_handshake_data;
6438 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006439
6440 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6441 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6442 ASSERT_TRUE(CreateClientAndServer());
6443
6444 BufferedFlight client_flight, server_flight;
6445 buffered_flights.Set(client_.get(), &client_flight);
6446 buffered_flights.Set(server_.get(), &server_flight);
6447
David Benjamind6343572019-08-15 17:29:02 -04006448 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006449
David Benjamind6343572019-08-15 17:29:02 -04006450 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006451}
6452
6453// Test that excess data at one level is rejected. That is, if a single
6454// |SSL_provide_quic_data| call included both ServerHello and
6455// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6456// key change.
6457TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006458 AllowOutOfOrderWrites();
6459
David Benjamincc9d9352018-10-30 19:45:22 -05006460 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6461 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006462 // Switch everything to the initial level.
6463 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6464 MakeConstSpan(data, len));
6465 };
6466
David Benjamin1e859052020-02-09 16:04:58 -05006467 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6468 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006469
6470 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6471 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6472 ASSERT_TRUE(CreateClientAndServer());
6473
6474 // Send the ClientHello and ServerHello through Finished.
6475 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6476 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6477 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6478 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6479 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6480
6481 // The client is still waiting for the ServerHello at initial
6482 // encryption.
6483 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6484
David Benjamincc9d9352018-10-30 19:45:22 -05006485 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6486 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006487 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6488
6489 // The client reads ServerHello successfully, but then rejects the buffered
6490 // EncryptedExtensions on key change.
6491 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6492 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6493 uint32_t err = ERR_get_error();
6494 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006495 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006496
David Benjamin1e859052020-02-09 16:04:58 -05006497 // The client sends an alert in response to this. The alert is sent at
6498 // handshake level because we install write secrets before read secrets and
6499 // the error is discovered when installing the read secret. (How to send
6500 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006501 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006502 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006503 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006504
David Benjamin5298ef92020-03-13 12:17:30 -04006505 // Sanity-check handshake secrets. The error is discovered while setting the
6506 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006507 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006508 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006509}
6510
6511// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6512TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006513 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006514
6515 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6516 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6517 ASSERT_TRUE(CreateClientAndServer());
6518
6519 // Send the ClientHello and ServerHello through Finished.
6520 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6521 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6522 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6523 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6524 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6525
6526 // The client is still waiting for the ServerHello at initial
6527 // encryption.
6528 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6529
6530 // Data cannot be provided at the next level.
6531 std::vector<uint8_t> data;
6532 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006533 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006534 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6535 data.data(), data.size()));
6536 ERR_clear_error();
6537
6538 // Progress to EncryptedExtensions.
6539 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6540 data.data(), data.size()));
6541 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6542 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6543 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6544
6545 // Data cannot be provided at the previous level.
6546 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006547 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006548 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6549 data.data(), data.size()));
6550}
6551
6552TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006553 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006554
6555 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6556 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6557 ASSERT_TRUE(CreateClientAndServer());
6558
6559 size_t limit =
6560 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6561 uint8_t b = 0;
6562 for (size_t i = 0; i < limit; i++) {
6563 ASSERT_TRUE(
6564 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6565 }
6566
6567 EXPECT_FALSE(
6568 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6569}
6570
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006571// Provide invalid post-handshake data.
6572TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006573 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006574
6575 g_last_session = nullptr;
6576
6577 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6578 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6579 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6580 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6581 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006582 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006583
6584 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6585 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006586 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6587 EXPECT_FALSE(transport_->client()->has_alert());
6588 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006589
6590 // Junk sent as part of post-handshake data should cause an error.
6591 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6592 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6593 kJunk, sizeof(kJunk)));
6594 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6595}
6596
Nick Harper80ddfc72020-03-11 18:26:31 -07006597static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6598 Span<const uint8_t> expected) {
6599 const uint8_t *received;
6600 size_t received_len;
6601 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6602 ASSERT_EQ(received_len, expected.size());
6603 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6604}
6605
6606TEST_F(QUICMethodTest, SetTransportParameters) {
6607 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6608 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6609 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6610
6611 ASSERT_TRUE(CreateClientAndServer());
6612 uint8_t kClientParams[] = {1, 2, 3, 4};
6613 uint8_t kServerParams[] = {5, 6, 7};
6614 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6615 sizeof(kClientParams)));
6616 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6617 sizeof(kServerParams)));
6618
6619 ASSERT_TRUE(CompleteHandshakesForQUIC());
6620 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6621 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6622}
6623
6624TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6625 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6626 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6627 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6628
6629 ASSERT_TRUE(CreateClientAndServer());
6630 uint8_t kClientParams[] = {1, 2, 3, 4};
6631 static uint8_t kServerParams[] = {5, 6, 7};
6632 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6633 sizeof(kClientParams)));
6634 SSL_CTX_set_tlsext_servername_callback(
6635 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6636 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6637 sizeof(kServerParams)));
6638 return SSL_TLSEXT_ERR_OK;
6639 });
6640
6641 ASSERT_TRUE(CompleteHandshakesForQUIC());
6642 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6643 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6644}
6645
Nick Harper6bfd25c2020-03-30 17:15:19 -07006646TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6647 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6648
6649 g_last_session = nullptr;
6650
6651 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6652 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6653 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6654 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6655
6656 ASSERT_TRUE(CreateClientAndServer());
6657 ASSERT_TRUE(CompleteHandshakesForQUIC());
6658
6659 ExpectHandshakeSuccess();
6660 EXPECT_FALSE(SSL_session_reused(client_.get()));
6661 EXPECT_FALSE(SSL_session_reused(server_.get()));
6662
6663 // The server sent NewSessionTicket messages in the handshake.
6664 EXPECT_FALSE(g_last_session);
6665 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6666 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6667 EXPECT_TRUE(g_last_session);
6668
6669 // Pretend that g_last_session came from a TLS-over-TCP connection.
6670 g_last_session.get()->is_quic = false;
6671
6672 // Create a second connection and verify that resumption does not occur with
6673 // a session from a non-QUIC connection. This tests that the client does not
6674 // offer over QUIC a session believed to be received over TCP. The server
6675 // believes this is a QUIC session, so if the client offered the session, the
6676 // server would have resumed it.
6677 ASSERT_TRUE(CreateClientAndServer());
6678 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6679 SSL_set_session(client_.get(), session.get());
6680
6681 ASSERT_TRUE(CompleteHandshakesForQUIC());
6682 ExpectHandshakeSuccess();
6683 EXPECT_FALSE(SSL_session_reused(client_.get()));
6684 EXPECT_FALSE(SSL_session_reused(server_.get()));
6685}
6686
6687TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6688 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6689
6690 g_last_session = nullptr;
6691
6692 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6693 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6694 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6695 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6696
6697 ASSERT_TRUE(CreateClientAndServer());
6698 ASSERT_TRUE(CompleteHandshakesForQUIC());
6699
6700 ExpectHandshakeSuccess();
6701 EXPECT_FALSE(SSL_session_reused(client_.get()));
6702 EXPECT_FALSE(SSL_session_reused(server_.get()));
6703
6704 // The server sent NewSessionTicket messages in the handshake.
6705 EXPECT_FALSE(g_last_session);
6706 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6707 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6708 EXPECT_TRUE(g_last_session);
6709
6710 // Attempt a resumption with g_last_session using TLS_method.
6711 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6712 ASSERT_TRUE(client_ctx);
6713
6714 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6715
6716 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6717 server(SSL_new(server_ctx_.get()));
6718 ASSERT_TRUE(client);
6719 ASSERT_TRUE(server);
6720 SSL_set_connect_state(client.get());
6721 SSL_set_accept_state(server.get());
6722
6723 // The TLS-over-TCP client will refuse to resume with a quic session, so
6724 // mark is_quic = false to bypass the client check to test the server check.
6725 g_last_session.get()->is_quic = false;
6726 SSL_set_session(client.get(), g_last_session.get());
6727
6728 BIO *bio1, *bio2;
6729 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6730
6731 // SSL_set_bio takes ownership.
6732 SSL_set_bio(client.get(), bio1, bio1);
6733 SSL_set_bio(server.get(), bio2, bio2);
6734 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6735
6736 EXPECT_FALSE(SSL_session_reused(client.get()));
6737 EXPECT_FALSE(SSL_session_reused(server.get()));
6738}
6739
Nick Harper72cff812020-03-26 18:06:16 -07006740TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6741 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6742 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6743 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6744
6745 ASSERT_TRUE(CreateClientAndServer());
6746 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6747 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6748}
6749
6750TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6751 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6752 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6753 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6754
6755 ASSERT_TRUE(CreateClientAndServer());
6756 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6757 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6758}
6759
David Schinazi3d8b8c32021-01-14 11:25:49 -08006760TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6761 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6762 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6763 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6764
6765 ASSERT_TRUE(CreateClientAndServer());
6766 uint8_t kClientParams[] = {1, 2, 3, 4};
6767 uint8_t kServerParams[] = {5, 6, 7};
6768 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6769 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6770 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6771 sizeof(kClientParams)));
6772 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6773 sizeof(kServerParams)));
6774
6775 ASSERT_TRUE(CompleteHandshakesForQUIC());
6776 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6777 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6778}
6779
6780TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6781 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6782 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6783 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6784
6785 ASSERT_TRUE(CreateClientAndServer());
6786 uint8_t kClientParams[] = {1, 2, 3, 4};
6787 uint8_t kServerParams[] = {5, 6, 7};
6788 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6789 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6790 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6791 sizeof(kClientParams)));
6792 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6793 sizeof(kServerParams)));
6794
6795 ASSERT_TRUE(CompleteHandshakesForQUIC());
6796 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6797 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6798}
6799
6800TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6801 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6802 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6803 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6804
6805 ASSERT_TRUE(CreateClientAndServer());
6806 uint8_t kClientParams[] = {1, 2, 3, 4};
6807 uint8_t kServerParams[] = {5, 6, 7};
6808 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6809 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6810 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6811 sizeof(kClientParams)));
6812 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6813 sizeof(kServerParams)));
6814
6815 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6816}
6817
6818TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6819 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6820 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6821 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6822
6823 ASSERT_TRUE(CreateClientAndServer());
6824 uint8_t kClientParams[] = {1, 2, 3, 4};
6825 uint8_t kServerParams[] = {5, 6, 7};
6826 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6827 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6828 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6829 sizeof(kClientParams)));
6830 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6831 sizeof(kServerParams)));
6832
6833 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6834}
6835
David Benjaminc47bfce2021-01-20 17:10:32 -05006836// Test that the default QUIC code point is consistent with
6837// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6838// update the two values together.
6839TEST_F(QUICMethodTest, QuicCodePointDefault) {
6840 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6841 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6842 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6843 SSL_CTX_set_select_certificate_cb(
6844 server_ctx_.get(),
6845 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6846 const uint8_t *data;
6847 size_t len;
6848 if (!SSL_early_callback_ctx_extension_get(
6849 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6850 &len)) {
6851 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6852 return ssl_select_cert_error;
6853 }
6854 return ssl_select_cert_success;
6855 });
6856
6857 ASSERT_TRUE(CreateClientAndServer());
6858 ASSERT_TRUE(CompleteHandshakesForQUIC());
6859}
6860
Adam Langley7540cc22019-04-18 09:56:13 -07006861extern "C" {
6862int BORINGSSL_enum_c_type_test(void);
6863}
6864
6865TEST(SSLTest, EnumTypes) {
6866 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6867 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6868}
6869
David Benjaminb29e1e12019-05-06 14:44:46 -05006870TEST_P(SSLVersionTest, DoubleSSLError) {
6871 // Connect the inner SSL connections.
6872 ASSERT_TRUE(Connect());
6873
6874 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6875 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6876 ASSERT_TRUE(bio_method);
6877 ASSERT_TRUE(BIO_meth_set_read(
6878 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6879 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6880 int ret = SSL_read(ssl, out, len);
6881 int ssl_ret = SSL_get_error(ssl, ret);
6882 if (ssl_ret == SSL_ERROR_WANT_READ) {
6883 BIO_set_retry_read(bio);
6884 }
6885 return ret;
6886 }));
6887 ASSERT_TRUE(BIO_meth_set_write(
6888 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6889 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6890 int ret = SSL_write(ssl, in, len);
6891 int ssl_ret = SSL_get_error(ssl, ret);
6892 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6893 BIO_set_retry_write(bio);
6894 }
6895 return ret;
6896 }));
6897 ASSERT_TRUE(BIO_meth_set_ctrl(
6898 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6899 // |SSL| objects require |BIO_flush| support.
6900 if (cmd == BIO_CTRL_FLUSH) {
6901 return 1;
6902 }
6903 return 0;
6904 }));
6905
6906 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6907 ASSERT_TRUE(client_bio);
6908 BIO_set_data(client_bio.get(), client_.get());
6909 BIO_set_init(client_bio.get(), 1);
6910
6911 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6912 ASSERT_TRUE(server_bio);
6913 BIO_set_data(server_bio.get(), server_.get());
6914 BIO_set_init(server_bio.get(), 1);
6915
6916 // Wrap the inner connections in another layer of SSL.
6917 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6918 ASSERT_TRUE(client_outer);
6919 SSL_set_connect_state(client_outer.get());
6920 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6921 client_bio.release(); // |SSL_set_bio| takes ownership.
6922
6923 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6924 ASSERT_TRUE(server_outer);
6925 SSL_set_accept_state(server_outer.get());
6926 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6927 server_bio.release(); // |SSL_set_bio| takes ownership.
6928
6929 // Configure |client_outer| to reject the server certificate.
6930 SSL_set_custom_verify(
6931 client_outer.get(), SSL_VERIFY_PEER,
6932 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6933 return ssl_verify_invalid;
6934 });
6935
6936 for (;;) {
6937 int client_ret = SSL_do_handshake(client_outer.get());
6938 int client_err = SSL_get_error(client_outer.get(), client_ret);
6939 if (client_err != SSL_ERROR_WANT_READ &&
6940 client_err != SSL_ERROR_WANT_WRITE) {
6941 // The client handshake should terminate on a certificate verification
6942 // error.
6943 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6944 uint32_t err = ERR_peek_error();
6945 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6946 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6947 break;
6948 }
6949
6950 // Run the server handshake and continue.
6951 int server_ret = SSL_do_handshake(server_outer.get());
6952 int server_err = SSL_get_error(server_outer.get(), server_ret);
6953 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6954 server_err == SSL_ERROR_WANT_READ ||
6955 server_err == SSL_ERROR_WANT_WRITE);
6956 }
6957}
6958
David Benjamin1b819472020-06-09 14:01:02 -04006959TEST_P(SSLVersionTest, SameKeyResume) {
6960 uint8_t key[48];
6961 RAND_bytes(key, sizeof(key));
6962
6963 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6964 ASSERT_TRUE(server_ctx2);
6965 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6966 ASSERT_TRUE(
6967 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6968 ASSERT_TRUE(
6969 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6970
6971 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6972 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6973 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6974
6975 // Establish a session for |server_ctx_|.
6976 bssl::UniquePtr<SSL_SESSION> session =
6977 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6978 ASSERT_TRUE(session);
6979 ClientConfig config;
6980 config.session = session.get();
6981
6982 // Resuming with |server_ctx_| again works.
6983 bssl::UniquePtr<SSL> client, server;
6984 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6985 server_ctx_.get(), config));
6986 EXPECT_TRUE(SSL_session_reused(client.get()));
6987 EXPECT_TRUE(SSL_session_reused(server.get()));
6988
6989 // Resuming with |server_ctx2| also works.
6990 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6991 server_ctx2.get(), config));
6992 EXPECT_TRUE(SSL_session_reused(client.get()));
6993 EXPECT_TRUE(SSL_session_reused(server.get()));
6994}
6995
6996TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6997 uint8_t key1[48], key2[48];
6998 RAND_bytes(key1, sizeof(key1));
6999 RAND_bytes(key2, sizeof(key2));
7000
7001 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7002 ASSERT_TRUE(server_ctx2);
7003 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7004 ASSERT_TRUE(
7005 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7006 ASSERT_TRUE(
7007 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7008
7009 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7010 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7011 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7012
7013 // Establish a session for |server_ctx_|.
7014 bssl::UniquePtr<SSL_SESSION> session =
7015 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7016 ASSERT_TRUE(session);
7017 ClientConfig config;
7018 config.session = session.get();
7019
7020 // Resuming with |server_ctx_| again works.
7021 bssl::UniquePtr<SSL> client, server;
7022 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7023 server_ctx_.get(), config));
7024 EXPECT_TRUE(SSL_session_reused(client.get()));
7025 EXPECT_TRUE(SSL_session_reused(server.get()));
7026
7027 // Resuming with |server_ctx2| does not work.
7028 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7029 server_ctx2.get(), config));
7030 EXPECT_FALSE(SSL_session_reused(client.get()));
7031 EXPECT_FALSE(SSL_session_reused(server.get()));
7032}
7033
7034TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7035 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7036 ASSERT_TRUE(server_ctx2);
7037 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7038
7039 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7040 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7041 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7042
7043 // Establish a session for |server_ctx_|.
7044 bssl::UniquePtr<SSL_SESSION> session =
7045 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7046 ASSERT_TRUE(session);
7047 ClientConfig config;
7048 config.session = session.get();
7049
7050 // Resuming with |server_ctx_| again works.
7051 bssl::UniquePtr<SSL> client, server;
7052 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7053 server_ctx_.get(), config));
7054 EXPECT_TRUE(SSL_session_reused(client.get()));
7055 EXPECT_TRUE(SSL_session_reused(server.get()));
7056
7057 // Resuming with |server_ctx2| does not work.
7058 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7059 server_ctx2.get(), config));
7060 EXPECT_FALSE(SSL_session_reused(client.get()));
7061 EXPECT_FALSE(SSL_session_reused(server.get()));
7062}
7063
Adam Langley47cefed2021-05-26 13:36:40 -07007064Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7065 const SSL_SESSION *session = SSL_get_session(ssl);
7066 unsigned len;
7067 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7068 return MakeConstSpan(data, len);
7069}
7070
7071TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7072 // This checks that the session IDs at client and server match after a ticket
7073 // resumption. It's unclear whether this should be true, but Envoy depends
7074 // on it in their tests so this will give an early signal if we break it.
7075 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7076 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7077
7078 bssl::UniquePtr<SSL_SESSION> session =
7079 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7080
7081 bssl::UniquePtr<SSL> client, server;
7082 ClientConfig config;
7083 config.session = session.get();
7084 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7085 server_ctx_.get(), config));
7086 EXPECT_TRUE(SSL_session_reused(client.get()));
7087 EXPECT_TRUE(SSL_session_reused(server.get()));
7088
7089 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7090}
7091
David Benjamin0e7dbd52019-05-15 16:01:18 -04007092TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04007093 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007094 ASSERT_TRUE(ctx);
7095
David Benjamin0e7dbd52019-05-15 16:01:18 -04007096 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7097 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7098 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7099 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7100
7101 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007102 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007103 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04007104 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007105
7106 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7107
7108 // Write "hello" until the buffer is full, so |client| has a pending write.
7109 size_t num_writes = 0;
7110 for (;;) {
7111 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7112 if (ret != int(sizeof(kInput))) {
7113 ASSERT_EQ(-1, ret);
7114 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7115 break;
7116 }
7117 num_writes++;
7118 }
7119
7120 // Encrypt a HelloRequest.
7121 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7122#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7123 // Fuzzer-mode records are unencrypted.
7124 uint8_t record[5 + sizeof(in)];
7125 record[0] = SSL3_RT_HANDSHAKE;
7126 record[1] = 3;
7127 record[2] = 3; // TLS 1.2
7128 record[3] = 0;
7129 record[4] = sizeof(record) - 5;
7130 memcpy(record + 5, in, sizeof(in));
7131#else
7132 // Extract key material from |server|.
7133 static const size_t kKeyLen = 32;
7134 static const size_t kNonceLen = 12;
7135 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
7136 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
7137 ASSERT_TRUE(
7138 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
7139 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7140 Span<uint8_t> nonce =
7141 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7142
7143 uint8_t ad[13];
7144 uint64_t seq = SSL_get_write_sequence(server.get());
7145 for (size_t i = 0; i < 8; i++) {
7146 // The nonce is XORed with the sequence number.
7147 nonce[11 - i] ^= uint8_t(seq);
7148 ad[7 - i] = uint8_t(seq);
7149 seq >>= 8;
7150 }
7151
7152 ad[8] = SSL3_RT_HANDSHAKE;
7153 ad[9] = 3;
7154 ad[10] = 3; // TLS 1.2
7155 ad[11] = 0;
7156 ad[12] = sizeof(in);
7157
7158 uint8_t record[5 + sizeof(in) + 16];
7159 record[0] = SSL3_RT_HANDSHAKE;
7160 record[1] = 3;
7161 record[2] = 3; // TLS 1.2
7162 record[3] = 0;
7163 record[4] = sizeof(record) - 5;
7164
7165 ScopedEVP_AEAD_CTX aead;
7166 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7167 key.data(), key.size(),
7168 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7169 size_t len;
7170 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7171 sizeof(record) - 5, nonce.data(), nonce.size(),
7172 in, sizeof(in), ad, sizeof(ad)));
7173 ASSERT_EQ(sizeof(record) - 5, len);
7174#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7175
7176 ASSERT_EQ(int(sizeof(record)),
7177 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
7178
7179 // |SSL_read| should pick up the HelloRequest.
7180 uint8_t byte;
7181 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7182 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7183
7184 // Drain the data from the |client|.
7185 uint8_t buf[sizeof(kInput)];
7186 for (size_t i = 0; i < num_writes; i++) {
7187 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7188 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7189 }
7190
7191 // |client| should be able to finish the pending write and continue to write,
7192 // despite the paused HelloRequest.
7193 ASSERT_EQ(int(sizeof(kInput)),
7194 SSL_write(client.get(), kInput, sizeof(kInput)));
7195 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7196 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7197
7198 ASSERT_EQ(int(sizeof(kInput)),
7199 SSL_write(client.get(), kInput, sizeof(kInput)));
7200 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7201 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7202
7203 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7204 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7205 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7206
7207 ASSERT_TRUE(SSL_renegotiate(client.get()));
7208 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7209 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7210
7211 // We never renegotiate as a server.
7212 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7213 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7214 uint32_t err = ERR_get_error();
7215 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7216 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7217}
7218
David Benjaminf9e0cda2020-03-23 18:29:09 -04007219
7220TEST(SSLTest, CopyWithoutEarlyData) {
7221 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007222 bssl::UniquePtr<SSL_CTX> server_ctx(
7223 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007224 ASSERT_TRUE(client_ctx);
7225 ASSERT_TRUE(server_ctx);
7226
David Benjaminf9e0cda2020-03-23 18:29:09 -04007227 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7228 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7229 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7230 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7231
7232 bssl::UniquePtr<SSL_SESSION> session =
7233 CreateClientSession(client_ctx.get(), server_ctx.get());
7234 ASSERT_TRUE(session);
7235
7236 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007237 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007238 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7239 server_ctx.get()));
7240 SSL_set_session(client.get(), session.get());
7241 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007242 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7243 EXPECT_TRUE(SSL_in_early_data(client.get()));
7244
7245 // |SSL_SESSION_copy_without_early_data| should disable early data but
7246 // still resume the session.
7247 bssl::UniquePtr<SSL_SESSION> session2(
7248 SSL_SESSION_copy_without_early_data(session.get()));
7249 ASSERT_TRUE(session2);
7250 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007251 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7252 server_ctx.get()));
7253 SSL_set_session(client.get(), session2.get());
7254 SSL_set_early_data_enabled(client.get(), 1);
7255 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007256 EXPECT_TRUE(SSL_session_reused(client.get()));
7257 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7258 SSL_get_early_data_reason(client.get()));
7259
7260 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7261 // when passed an early-data-incapable session.
7262 bssl::UniquePtr<SSL_SESSION> session3(
7263 SSL_SESSION_copy_without_early_data(session2.get()));
7264 EXPECT_EQ(session2.get(), session3.get());
7265}
7266
Adam Langley53a17f52020-05-26 14:44:07 -07007267TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7268 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007269 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007270 bssl::UniquePtr<SSL_CTX> server_ctx(
7271 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007272 ASSERT_TRUE(client_ctx);
7273 ASSERT_TRUE(server_ctx);
7274 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7275 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7276 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7277 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007278
7279 bssl::UniquePtr<SSL> client, server;
7280 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7281 server_ctx.get()));
7282 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7283
7284 // Process a TLS 1.3 NewSessionTicket.
7285 static const uint8_t kTicket[] = {
7286 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7287 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7288 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7289 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7290 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7291 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7292 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7293 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7294 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7295 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7296 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7297 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7298 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7299 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7300 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7301 0x00, 0x00,
7302 };
7303 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7304 client.get(), kTicket, sizeof(kTicket)));
7305 ASSERT_TRUE(session);
7306 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7307
7308 uint8_t *session_buf = nullptr;
7309 size_t session_length = 0;
7310 ASSERT_TRUE(
7311 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7312 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7313 ASSERT_TRUE(session_buf);
7314 ASSERT_GT(session_length, 0u);
7315
7316 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7317 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7318 sizeof(kTicket)));
7319
7320 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7321 // handshake completes.
7322 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7323 ASSERT_TRUE(client2);
7324 SSL_set_connect_state(client2.get());
7325 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7326 sizeof(kTicket)));
7327}
7328
David Benjamin3989c992020-10-09 14:12:06 -04007329TEST(SSLTest, BIO) {
7330 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007331 bssl::UniquePtr<SSL_CTX> server_ctx(
7332 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007333 ASSERT_TRUE(client_ctx);
7334 ASSERT_TRUE(server_ctx);
7335
David Benjamin3989c992020-10-09 14:12:06 -04007336 for (bool take_ownership : {true, false}) {
7337 // For simplicity, get the handshake out of the way first.
7338 bssl::UniquePtr<SSL> client, server;
7339 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7340 server_ctx.get()));
7341
7342 // Wrap |client| in an SSL BIO.
7343 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7344 ASSERT_TRUE(client_bio);
7345 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7346 if (take_ownership) {
7347 client.release();
7348 }
7349
7350 // Flushing the BIO should not crash.
7351 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7352
7353 // Exchange some data.
7354 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7355 uint8_t buf[5];
7356 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7357 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7358
7359 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7360 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7361 EXPECT_EQ(Bytes("world"), Bytes(buf));
7362
7363 // |BIO_should_read| should work.
7364 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7365 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7366
7367 // Writing data should eventually exceed the buffer size and fail, reporting
7368 // |BIO_should_write|.
7369 int ret;
7370 for (int i = 0; i < 1024; i++) {
7371 std::vector<uint8_t> buffer(1024);
7372 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7373 if (ret <= 0) {
7374 break;
7375 }
7376 }
7377 EXPECT_EQ(-1, ret);
7378 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7379 }
7380}
7381
David Benjamin12a3e7e2021-04-13 11:47:36 -04007382TEST(SSLTest, ALPNConfig) {
7383 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7384 ASSERT_TRUE(ctx);
7385 bssl::UniquePtr<X509> cert = GetTestCertificate();
7386 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7387 ASSERT_TRUE(cert);
7388 ASSERT_TRUE(key);
7389 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7390 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7391
7392 // Set up some machinery to check the configured ALPN against what is actually
7393 // sent over the wire. Note that the ALPN callback is only called when the
7394 // client offers ALPN.
7395 std::vector<uint8_t> observed_alpn;
7396 SSL_CTX_set_alpn_select_cb(
7397 ctx.get(),
7398 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7399 unsigned in_len, void *arg) -> int {
7400 std::vector<uint8_t> *observed_alpn_ptr =
7401 static_cast<std::vector<uint8_t> *>(arg);
7402 observed_alpn_ptr->assign(in, in + in_len);
7403 return SSL_TLSEXT_ERR_NOACK;
7404 },
7405 &observed_alpn);
7406 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7407 observed_alpn.clear();
7408 bssl::UniquePtr<SSL> client, server;
7409 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7410 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7411 };
7412
7413 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7414 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7415 0x03, 'b', 'a', 'r'};
7416 EXPECT_EQ(0,
7417 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7418 check_alpn_proto(kValidList);
7419
7420 // Invalid lists are rejected.
7421 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7422 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7423 sizeof(kInvalidList)));
7424
7425 // Empty lists are valid and are interpreted as disabling ALPN.
7426 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7427 check_alpn_proto({});
7428}
7429
David Benjamin2f3958a2021-04-16 11:55:23 -04007430// Test that the key usage checker can correctly handle issuerUID and
7431// subjectUID. See https://crbug.com/1199744.
7432TEST(SSLTest, KeyUsageWithUIDs) {
7433 static const char kGoodKeyUsage[] = R"(
7434-----BEGIN CERTIFICATE-----
7435MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7436AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7437aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7438CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7439ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
74404r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7441Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7442ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7443A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
744434EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
74454Z7qDhjIhiF4dM0uEDYRVA==
7446-----END CERTIFICATE-----
7447)";
7448 static const char kBadKeyUsage[] = R"(
7449-----BEGIN CERTIFICATE-----
7450MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7451AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7452aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7453CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7454ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
74554r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7456Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7457ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7458A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7459taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7460RHrQbWsFUakETXL9QMlegh5t
7461-----END CERTIFICATE-----
7462)";
7463
7464 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7465 ASSERT_TRUE(good);
7466 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7467 ASSERT_TRUE(bad);
7468
7469 // We check key usage when configuring EC certificates to distinguish ECDSA
7470 // and ECDH.
7471 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7472 ASSERT_TRUE(ctx);
7473 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7474 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7475}
7476
David Benjamin9b2cdb72021-04-01 23:21:53 -04007477// Test that |SSL_can_release_private_key| reports true as early as expected.
7478// The internal asserts in the library check we do not report true too early.
7479TEST(SSLTest, CanReleasePrivateKey) {
7480 bssl::UniquePtr<SSL_CTX> client_ctx =
7481 CreateContextWithTestCertificate(TLS_method());
7482 ASSERT_TRUE(client_ctx);
7483 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7484
7485 // Note this assumes the transport buffer is large enough to fit the client
7486 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7487 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7488 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7489 // Write the ClientHello.
7490 ASSERT_EQ(-1, SSL_do_handshake(client));
7491 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7492
7493 // Consume the ClientHello and write the server flight.
7494 ASSERT_EQ(-1, SSL_do_handshake(server));
7495 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7496
7497 EXPECT_TRUE(SSL_can_release_private_key(server));
7498 };
7499
7500 {
7501 SCOPED_TRACE("TLS 1.2 ECDHE");
7502 bssl::UniquePtr<SSL_CTX> server_ctx(
7503 CreateContextWithTestCertificate(TLS_method()));
7504 ASSERT_TRUE(server_ctx);
7505 ASSERT_TRUE(
7506 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7507 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7508 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7509 // Configure the server to request client certificates, so we can also test
7510 // the client half.
7511 SSL_CTX_set_custom_verify(
7512 server_ctx.get(), SSL_VERIFY_PEER,
7513 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7514 bssl::UniquePtr<SSL> client, server;
7515 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7516 server_ctx.get()));
7517 check_first_server_round_trip(client.get(), server.get());
7518
7519 // Consume the server flight and write the client response. The client still
7520 // has a Finished message to consume but can also release its key early.
7521 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7522 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7523 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7524
7525 // However, a client that has not disabled renegotiation can never release
7526 // the key.
7527 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7528 server_ctx.get()));
7529 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7530 check_first_server_round_trip(client.get(), server.get());
7531 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7532 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7533 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7534 }
7535
7536 {
7537 SCOPED_TRACE("TLS 1.2 resumption");
7538 bssl::UniquePtr<SSL_CTX> server_ctx(
7539 CreateContextWithTestCertificate(TLS_method()));
7540 ASSERT_TRUE(server_ctx);
7541 ASSERT_TRUE(
7542 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7543 bssl::UniquePtr<SSL_SESSION> session =
7544 CreateClientSession(client_ctx.get(), server_ctx.get());
7545 ASSERT_TRUE(session);
7546 bssl::UniquePtr<SSL> client, server;
7547 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7548 server_ctx.get()));
7549 SSL_set_session(client.get(), session.get());
7550 check_first_server_round_trip(client.get(), server.get());
7551 }
7552
7553 {
7554 SCOPED_TRACE("TLS 1.3 1-RTT");
7555 bssl::UniquePtr<SSL_CTX> server_ctx(
7556 CreateContextWithTestCertificate(TLS_method()));
7557 ASSERT_TRUE(server_ctx);
7558 ASSERT_TRUE(
7559 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7560 bssl::UniquePtr<SSL> client, server;
7561 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7562 server_ctx.get()));
7563 check_first_server_round_trip(client.get(), server.get());
7564 }
7565
7566 {
7567 SCOPED_TRACE("TLS 1.3 resumption");
7568 bssl::UniquePtr<SSL_CTX> server_ctx(
7569 CreateContextWithTestCertificate(TLS_method()));
7570 ASSERT_TRUE(server_ctx);
7571 ASSERT_TRUE(
7572 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7573 bssl::UniquePtr<SSL_SESSION> session =
7574 CreateClientSession(client_ctx.get(), server_ctx.get());
7575 ASSERT_TRUE(session);
7576 bssl::UniquePtr<SSL> client, server;
7577 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7578 server_ctx.get()));
7579 SSL_set_session(client.get(), session.get());
7580 check_first_server_round_trip(client.get(), server.get());
7581 }
7582}
7583
David Benjamine9c5d722021-06-09 17:43:16 -04007584// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7585// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7586// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7587// will be set to the ClientHelloInner's extensions, rather than
7588// ClientHelloOuter.
7589static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7590 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7591 struct AppData {
7592 std::vector<uint16_t> *out;
7593 bool decrypt_ech;
7594 bool callback_done = false;
7595 };
7596 AppData app_data;
7597 app_data.out = out;
7598 app_data.decrypt_ech = decrypt_ech;
7599
7600 bssl::UniquePtr<SSL_CTX> server_ctx =
7601 CreateContextWithTestCertificate(TLS_method());
7602 if (!server_ctx || //
7603 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7604 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7605 return false;
7606 }
7607
7608 // Configure the server to record the ClientHello extension order. We use a
7609 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7610 SSL_CTX_set_select_certificate_cb(
7611 server_ctx.get(),
7612 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7613 AppData *app_data_ptr = static_cast<AppData *>(
7614 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7615 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7616 SSL_ech_accepted(client_hello->ssl));
7617
7618 app_data_ptr->out->clear();
7619 CBS extensions;
7620 CBS_init(&extensions, client_hello->extensions,
7621 client_hello->extensions_len);
7622 while (CBS_len(&extensions)) {
7623 uint16_t type;
7624 CBS body;
7625 if (!CBS_get_u16(&extensions, &type) ||
7626 !CBS_get_u16_length_prefixed(&extensions, &body)) {
7627 return ssl_select_cert_error;
7628 }
7629 app_data_ptr->out->push_back(type);
7630 }
7631
7632 // Don't bother completing the handshake.
7633 app_data_ptr->callback_done = true;
7634 return ssl_select_cert_error;
7635 });
7636
7637 bssl::UniquePtr<SSL> client, server;
7638 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
7639 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
7640 return false;
7641 }
7642
7643 // Run the handshake far enough to process the ClientHello.
7644 SSL_do_handshake(client.get());
7645 SSL_do_handshake(server.get());
7646 return app_data.callback_done;
7647}
7648
7649// Test that, when extension permutation is enabled, the ClientHello extension
7650// order changes, both with and without ECH, and in both ClientHelloInner and
7651// ClientHelloOuter.
7652TEST(SSLTest, PermuteExtensions) {
7653 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
7654 ASSERT_TRUE(keys);
7655 for (bool offer_ech : {false, true}) {
7656 SCOPED_TRACE(offer_ech);
7657 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
7658 for (bool decrypt_ech : {false, true}) {
7659 SCOPED_TRACE(decrypt_ech);
7660 if (!offer_ech && decrypt_ech) {
7661 continue;
7662 }
7663
7664 // When extension permutation is disabled, the order should be consistent.
7665 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7666 ASSERT_TRUE(ctx);
7667 std::vector<uint16_t> order1, order2;
7668 ASSERT_TRUE(
7669 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7670 ASSERT_TRUE(
7671 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7672 EXPECT_EQ(order1, order2);
7673
7674 ctx.reset(SSL_CTX_new(TLS_method()));
7675 ASSERT_TRUE(ctx);
7676 SSL_CTX_set_permute_extensions(ctx.get(), 1);
7677
7678 // When extension permutation is enabled, each ClientHello should have a
7679 // different order.
7680 //
7681 // This test is inherently flaky, so we run it multiple times. We send at
7682 // least five extensions by default from TLS 1.3: supported_versions,
7683 // key_share, supported_groups, psk_key_exchange_modes, and
7684 // signature_algorithms. That means the probability of a false negative is
7685 // at most 1/120. Repeating the test 14 times lowers false negative rate
7686 // to under 2^-96.
7687 ASSERT_TRUE(
7688 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7689 EXPECT_GE(order1.size(), 5u);
7690 static const int kNumIterations = 14;
7691 bool passed = false;
7692 for (int i = 0; i < kNumIterations; i++) {
7693 ASSERT_TRUE(
7694 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7695 if (order1 != order2) {
7696 passed = true;
7697 break;
7698 }
7699 }
7700 EXPECT_TRUE(passed) << "Extensions were not permuted";
7701 }
7702 }
7703}
7704
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007705} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007706BSSL_NAMESPACE_END