blob: e2a41b86654e798d9e4ce937d7ebdfe4df16fa1d [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 Benjaminc79ae7a2017-08-29 16:09:44 -04001536// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1537// before configuring as a server.
1538TEST(SSLTest, ClientCAList) {
1539 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1540 ASSERT_TRUE(ctx);
1541 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1542 ASSERT_TRUE(ssl);
1543
1544 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1545 ASSERT_TRUE(name);
1546
1547 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1548 ASSERT_TRUE(name_dup);
1549
1550 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1551 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001552 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001553
1554 // |SSL_set_client_CA_list| takes ownership.
1555 SSL_set_client_CA_list(ssl.get(), stack.release());
1556
1557 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1558 ASSERT_TRUE(result);
1559 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1560 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1561}
1562
1563TEST(SSLTest, AddClientCA) {
1564 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1565 ASSERT_TRUE(ctx);
1566 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1567 ASSERT_TRUE(ssl);
1568
1569 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1570 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1571 ASSERT_TRUE(cert1 && cert2);
1572 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1573 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1574
1575 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1576
1577 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1578 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1579
1580 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1581 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1582 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1583 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1584
1585 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1586
1587 list = SSL_get_client_CA_list(ssl.get());
1588 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1589 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1590 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1591 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1592}
1593
David Benjamin24545c52021-06-07 16:05:07 -04001594struct ECHConfigParams {
1595 uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1596 uint16_t config_id = 1;
1597 std::string public_name = "example.com";
1598 const EVP_HPKE_KEY *key = nullptr;
1599 // kem_id, if zero, takes its value from |key|.
1600 uint16_t kem_id = 0;
1601 // public_key, if empty takes its value from |key|.
1602 std::vector<uint8_t> public_key;
1603 size_t max_name_len = 16;
1604 // cipher_suites is a list of code points which should contain pairs of KDF
1605 // and AEAD IDs.
1606 std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1607 EVP_HPKE_AES_128_GCM};
1608 std::vector<uint8_t> extensions;
1609};
Daniel McArdle00e434d2021-02-18 11:47:18 -05001610
David Benjamin24545c52021-06-07 16:05:07 -04001611// MakeECHConfig serializes an ECHConfig from |params| and writes it to
1612// |*out|.
1613bool MakeECHConfig(std::vector<uint8_t> *out,
1614 const ECHConfigParams &params) {
1615 uint16_t kem_id = params.kem_id == 0
1616 ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1617 : params.kem_id;
1618 std::vector<uint8_t> public_key = params.public_key;
1619 if (public_key.empty()) {
1620 public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1621 size_t len;
1622 if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1623 public_key.size())) {
1624 return false;
1625 }
1626 public_key.resize(len);
1627 }
Daniel McArdle00e434d2021-02-18 11:47:18 -05001628
Daniel McArdle00e434d2021-02-18 11:47:18 -05001629 bssl::ScopedCBB cbb;
1630 CBB contents, child;
Daniel McArdle00e434d2021-02-18 11:47:18 -05001631 if (!CBB_init(cbb.get(), 64) ||
David Benjamin24545c52021-06-07 16:05:07 -04001632 !CBB_add_u16(cbb.get(), params.version) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001633 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
David Benjamin24545c52021-06-07 16:05:07 -04001634 !CBB_add_u8(&contents, params.config_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001635 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001636 !CBB_add_u16_length_prefixed(&contents, &child) ||
1637 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001638 !CBB_add_u16_length_prefixed(&contents, &child)) {
1639 return false;
1640 }
David Benjamin24545c52021-06-07 16:05:07 -04001641 for (uint16_t cipher_suite : params.cipher_suites) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001642 if (!CBB_add_u16(&child, cipher_suite)) {
1643 return false;
1644 }
1645 }
David Benjamin24545c52021-06-07 16:05:07 -04001646 if (!CBB_add_u16(&contents, params.max_name_len) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001647 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001648 !CBB_add_bytes(
1649 &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1650 params.public_name.size()) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001651 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001652 !CBB_add_bytes(&child, params.extensions.data(),
1653 params.extensions.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001654 !CBB_flush(cbb.get())) {
1655 return false;
1656 }
1657
1658 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1659 return true;
1660}
1661
David Benjamin83a49932021-05-20 15:57:09 -04001662static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys() {
1663 bssl::ScopedEVP_HPKE_KEY key;
1664 uint8_t *ech_config;
1665 size_t ech_config_len;
1666 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1667 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
1668 /*config_id=*/1, key.get(), "public.example",
1669 16)) {
1670 return nullptr;
1671 }
1672 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1673
1674 // Install a non-retry config.
1675 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1676 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1677 ech_config_len, key.get())) {
1678 return nullptr;
1679 }
1680 return keys;
1681}
1682
1683static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1684 uint8_t *ech_config_list;
1685 size_t ech_config_list_len;
1686 if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1687 &ech_config_list_len)) {
1688 return false;
1689 }
1690 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1691 return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1692}
1693
David Benjamin24545c52021-06-07 16:05:07 -04001694// Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1695// output values as expected.
1696TEST(SSLTest, MarshalECHConfig) {
1697 static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1698 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1699 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1700 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1701 bssl::ScopedEVP_HPKE_KEY key;
1702 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1703 kPrivateKey, sizeof(kPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001704
David Benjamin24545c52021-06-07 16:05:07 -04001705 static const uint8_t kECHConfig[] = {
1706 // version
1707 0xfe, 0x0a,
1708 // length
1709 0x00, 0x43,
1710 // contents.config_id
1711 0x01,
1712 // contents.kem_id
1713 0x00, 0x20,
1714 // contents.public_key
1715 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1716 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1717 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1718 // contents.cipher_suites
1719 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1720 // contents.maximum_name_length
1721 0x00, 0x10,
1722 // contents.public_name
1723 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1724 0x6d, 0x70, 0x6c, 0x65,
1725 // contents.extensions
1726 0x00, 0x00};
1727 uint8_t *ech_config;
1728 size_t ech_config_len;
1729 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1730 /*config_id=*/1, key.get(),
1731 "public.example", 16));
1732 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1733 EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1734
1735 // Generate a second ECHConfig.
1736 bssl::ScopedEVP_HPKE_KEY key2;
1737 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1738 uint8_t *ech_config2;
1739 size_t ech_config2_len;
1740 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1741 /*config_id=*/2, key2.get(),
1742 "public.example", 16));
1743 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1744
1745 // Install both ECHConfigs in an |SSL_ECH_KEYS|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001746 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1747 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001748 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1749 ech_config_len, key.get()));
1750 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1751 ech_config2_len, key2.get()));
1752
1753 // The ECHConfigList should be correctly serialized.
1754 uint8_t *ech_config_list;
1755 size_t ech_config_list_len;
1756 ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1757 &ech_config_list_len));
1758 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1759
1760 // ECHConfigList is just the concatenation with a length prefix.
1761 size_t len = ech_config_len + ech_config2_len;
1762 std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1763 expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1764 expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1765 EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
David Benjamin24545c52021-06-07 16:05:07 -04001766}
1767
1768TEST(SSLTest, ECHHasDuplicateConfigID) {
1769 const struct {
1770 std::vector<uint8_t> ids;
1771 bool has_duplicate;
1772 } kTests[] = {
1773 {{}, false},
1774 {{1}, false},
1775 {{1, 2, 3, 255}, false},
1776 {{1, 2, 3, 1}, true},
1777 };
1778 for (const auto &test : kTests) {
1779 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1780 ASSERT_TRUE(keys);
1781 for (const uint8_t id : test.ids) {
1782 bssl::ScopedEVP_HPKE_KEY key;
1783 ASSERT_TRUE(
1784 EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1785 uint8_t *ech_config;
1786 size_t ech_config_len;
1787 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
1788 key.get(), "public.example", 16));
1789 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1790 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1791 ech_config, ech_config_len, key.get()));
1792 }
1793
1794 EXPECT_EQ(test.has_duplicate ? 1 : 0,
1795 SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
1796 }
1797}
1798
1799// Test that |SSL_ECH_KEYS_add| checks consistency between the public and
1800// private key.
1801TEST(SSLTest, ECHKeyConsistency) {
1802 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1803 ASSERT_TRUE(keys);
1804 bssl::ScopedEVP_HPKE_KEY key;
1805 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1806 uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
1807 size_t public_key_len;
1808 ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
1809 sizeof(public_key)));
1810
1811 // Adding an ECHConfig with the matching public key succeeds.
1812 ECHConfigParams params;
1813 params.key = key.get();
1814 std::vector<uint8_t> ech_config;
1815 ASSERT_TRUE(MakeECHConfig(&ech_config, params));
1816 EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1817 ech_config.data(), ech_config.size(),
1818 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001819
David Benjaminc890ae52021-06-06 13:32:29 -04001820 // Adding an ECHConfig with the wrong public key is an error.
1821 bssl::ScopedEVP_HPKE_KEY wrong_key;
1822 ASSERT_TRUE(
1823 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjamin24545c52021-06-07 16:05:07 -04001824 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1825 ech_config.data(), ech_config.size(),
1826 wrong_key.get()));
1827
1828 // Adding an ECHConfig with a truncated public key is an error.
1829 ECHConfigParams truncated;
1830 truncated.key = key.get();
1831 truncated.public_key.assign(public_key, public_key + public_key_len - 1);
1832 ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
1833 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1834 ech_config.data(), ech_config.size(), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001835
David Benjaminc890ae52021-06-06 13:32:29 -04001836 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
1837 // error.
David Benjamin24545c52021-06-07 16:05:07 -04001838 ECHConfigParams wrong_kem;
1839 wrong_kem.key = key.get();
1840 wrong_kem.kem_id = 0x0010; // DHKEM(P-256, HKDF-SHA256)
1841 ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
David Benjaminc890ae52021-06-06 13:32:29 -04001842 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1843 ech_config.data(), ech_config.size(),
1844 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001845}
1846
David Benjaminc3b373b2021-06-06 13:04:26 -04001847// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001848// has no retry configs.
1849TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
David Benjamin24545c52021-06-07 16:05:07 -04001850 bssl::ScopedEVP_HPKE_KEY key;
1851 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1852 uint8_t *ech_config;
1853 size_t ech_config_len;
1854 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1855 /*config_id=*/1, key.get(),
1856 "public.example", 16));
1857 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001858
David Benjamin24545c52021-06-07 16:05:07 -04001859 // Install a non-retry config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001860 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1861 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001862 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
1863 ech_config_len, key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001864
David Benjamin24545c52021-06-07 16:05:07 -04001865 // |keys| has no retry configs.
1866 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1867 ASSERT_TRUE(ctx);
1868 EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001869
1870 // Add the same ECHConfig to the list, but this time mark it as a retry
1871 // config.
David Benjamin24545c52021-06-07 16:05:07 -04001872 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1873 ech_config_len, key.get()));
1874 EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001875}
1876
1877// Test that the server APIs reject ECHConfigs with unsupported features.
1878TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001879 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1880 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04001881 bssl::ScopedEVP_HPKE_KEY key;
David Benjamin24545c52021-06-07 16:05:07 -04001882 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001883
1884 // Unsupported versions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001885 ECHConfigParams unsupported_version;
1886 unsupported_version.version = 0xffff;
1887 unsupported_version.key = key.get();
Daniel McArdle00e434d2021-02-18 11:47:18 -05001888 std::vector<uint8_t> ech_config;
David Benjamin24545c52021-06-07 16:05:07 -04001889 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
David Benjaminc3b373b2021-06-06 13:04:26 -04001890 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1891 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001892 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001893
David Benjamin24545c52021-06-07 16:05:07 -04001894 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1895 ECHConfigParams unsupported_kdf;
1896 unsupported_kdf.key = key.get();
1897 unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
1898 EVP_HPKE_AES_128_GCM};
1899 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
1900 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1901 ech_config.data(), ech_config.size(),
1902 key.get()));
1903 ECHConfigParams unsupported_aead;
1904 unsupported_aead.key = key.get();
1905 unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
1906 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
1907 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1908 ech_config.data(), ech_config.size(),
1909 key.get()));
1910
1911
Daniel McArdle00e434d2021-02-18 11:47:18 -05001912 // Unsupported extensions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001913 ECHConfigParams extensions;
1914 extensions.key = key.get();
1915 extensions.extensions = {0x00, 0x01, 0x00, 0x00};
1916 ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001917 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1918 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001919 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001920}
1921
David Benjamin83a49932021-05-20 15:57:09 -04001922// Test that |SSL_get_client_random| reports the correct value on both client
1923// and server in ECH. The client sends two different random values. When ECH is
1924// accepted, we should report the inner one.
1925TEST(SSLTest, ECHClientRandomsMatch) {
1926 bssl::UniquePtr<SSL_CTX> server_ctx =
1927 CreateContextWithTestCertificate(TLS_method());
1928 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
1929 ASSERT_TRUE(keys);
1930 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
1931
1932 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1933 ASSERT_TRUE(client_ctx);
1934 bssl::UniquePtr<SSL> client, server;
1935 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
1936 server_ctx.get()));
1937 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
1938 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
1939
1940 EXPECT_TRUE(SSL_ech_accepted(client.get()));
1941 EXPECT_TRUE(SSL_ech_accepted(server.get()));
1942
1943 // An ECH server will fairly naturally record the inner ClientHello random,
1944 // but an ECH client may forget to update the random once ClientHelloInner is
1945 // selected.
1946 uint8_t client_random1[SSL3_RANDOM_SIZE];
1947 uint8_t client_random2[SSL3_RANDOM_SIZE];
1948 ASSERT_EQ(sizeof(client_random1),
1949 SSL_get_client_random(client.get(), client_random1,
1950 sizeof(client_random1)));
1951 ASSERT_EQ(sizeof(client_random2),
1952 SSL_get_client_random(server.get(), client_random2,
1953 sizeof(client_random2)));
1954 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
1955}
1956
1957// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
1958// of the ClientHello and ECH extension, respectively, when a client created
1959// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
1960// maximum name length |max_name_len|.
1961static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
1962 size_t *out_ech_len, size_t max_name_len,
1963 const char *name) {
1964 bssl::ScopedEVP_HPKE_KEY key;
1965 uint8_t *ech_config;
1966 size_t ech_config_len;
1967 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1968 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
1969 /*config_id=*/1, key.get(), "public.example",
1970 max_name_len)) {
1971 return false;
1972 }
1973 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1974
1975 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1976 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1977 ech_config_len, key.get())) {
1978 return false;
1979 }
1980
1981 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
1982 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
1983 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
1984 return false;
1985 }
1986 SSL_set_connect_state(ssl.get());
1987
1988 std::vector<uint8_t> client_hello;
1989 SSL_CLIENT_HELLO parsed;
1990 const uint8_t *unused;
1991 if (!GetClientHello(ssl.get(), &client_hello) ||
1992 !ssl_client_hello_init(
1993 ssl.get(), &parsed,
1994 // Skip record and handshake headers. This assumes the ClientHello
1995 // fits in one record.
1996 MakeConstSpan(client_hello)
1997 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
1998 !SSL_early_callback_ctx_extension_get(
1999 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2000 return false;
2001 }
2002 *out_client_hello_len = client_hello.size();
2003 return true;
2004}
2005
2006TEST(SSLTest, ECHPadding) {
2007 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2008 ASSERT_TRUE(ctx);
2009
2010 // Sample lengths with max_name_len = 128 as baseline.
2011 size_t client_hello_len_baseline, ech_len_baseline;
2012 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2013 &ech_len_baseline, 128, "example.com"));
2014
2015 // Check that all name lengths under the server's maximum look the same.
2016 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2017 SCOPED_TRACE(name_len);
2018 size_t client_hello_len, ech_len;
2019 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2020 std::string(name_len, 'a').c_str()));
2021 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2022 EXPECT_EQ(ech_len, ech_len_baseline);
2023 }
2024
2025 // When sending no SNI, we must still pad as if we are sending one.
2026 size_t client_hello_len, ech_len;
2027 ASSERT_TRUE(
2028 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2029 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2030 EXPECT_EQ(ech_len, ech_len_baseline);
2031
2032 size_t client_hello_len_129, ech_len_129;
2033 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_129, &ech_len_129, 128,
2034 std::string(129, 'a').c_str()));
2035 // The padding calculation should not pad beyond the maximum.
2036 EXPECT_GT(ech_len_129, ech_len_baseline);
2037
2038 // If the SNI exceeds the maximum name length, we apply some generic padding,
2039 // so close name lengths still match.
2040 for (size_t name_len : {129, 130, 131, 132}) {
2041 SCOPED_TRACE(name_len);
2042 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2043 std::string(name_len, 'a').c_str()));
2044 EXPECT_EQ(client_hello_len, client_hello_len_129);
2045 EXPECT_EQ(ech_len, ech_len_129);
2046 }
2047}
2048
2049#if defined(OPENSSL_THREADS)
2050// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2051// in use on other threads. This test is intended to be run with TSan.
2052TEST(SSLTest, ECHThreads) {
2053 // Generate a pair of ECHConfigs.
2054 bssl::ScopedEVP_HPKE_KEY key1;
2055 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2056 uint8_t *ech_config1;
2057 size_t ech_config1_len;
2058 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2059 /*config_id=*/1, key1.get(),
2060 "public.example", 16));
2061 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2062 bssl::ScopedEVP_HPKE_KEY key2;
2063 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2064 uint8_t *ech_config2;
2065 size_t ech_config2_len;
2066 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2067 /*config_id=*/2, key2.get(),
2068 "public.example", 16));
2069 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2070
2071 // |keys1| contains the first config. |keys12| contains both.
2072 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2073 ASSERT_TRUE(keys1);
2074 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2075 ech_config1_len, key1.get()));
2076 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2077 ASSERT_TRUE(keys12);
2078 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2079 ech_config2_len, key2.get()));
2080 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2081 ech_config1_len, key1.get()));
2082
2083 bssl::UniquePtr<SSL_CTX> server_ctx =
2084 CreateContextWithTestCertificate(TLS_method());
2085 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2086
2087 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2088 ASSERT_TRUE(client_ctx);
2089 bssl::UniquePtr<SSL> client, server;
2090 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2091 server_ctx.get()));
2092 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2093
2094 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2095 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2096 // the same whichever the server uses.
2097 std::vector<std::thread> threads;
2098 threads.emplace_back([&] {
2099 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2100 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2101 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2102 });
2103 threads.emplace_back([&] {
2104 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2105 });
2106 for (auto &thread : threads) {
2107 thread.join();
2108 }
2109}
2110#endif // OPENSSL_THREADS
2111
David Benjaminc79ae7a2017-08-29 16:09:44 -04002112static void AppendSession(SSL_SESSION *session, void *arg) {
2113 std::vector<SSL_SESSION*> *out =
2114 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2115 out->push_back(session);
2116}
2117
2118// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2119// order.
2120static bool CacheEquals(SSL_CTX *ctx,
2121 const std::vector<SSL_SESSION*> &expected) {
2122 // Check the linked list.
2123 SSL_SESSION *ptr = ctx->session_cache_head;
2124 for (SSL_SESSION *session : expected) {
2125 if (ptr != session) {
2126 return false;
2127 }
2128 // TODO(davidben): This is an absurd way to denote the end of the list.
2129 if (ptr->next ==
2130 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2131 ptr = nullptr;
2132 } else {
2133 ptr = ptr->next;
2134 }
2135 }
2136 if (ptr != nullptr) {
2137 return false;
2138 }
2139
2140 // Check the hash table.
2141 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002142 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002143 expected_copy = expected;
2144
2145 std::sort(actual.begin(), actual.end());
2146 std::sort(expected_copy.begin(), expected_copy.end());
2147
2148 return actual == expected_copy;
2149}
2150
2151static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2152 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2153 if (!ssl_ctx) {
2154 return nullptr;
2155 }
2156 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2157 if (!ret) {
2158 return nullptr;
2159 }
2160
David Benjaminaaef8332018-06-29 16:45:49 -04002161 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2162 OPENSSL_memcpy(id, &number, sizeof(number));
2163 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2164 return nullptr;
2165 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002166 return ret;
2167}
2168
2169// Test that the internal session cache behaves as expected.
2170TEST(SSLTest, InternalSessionCache) {
2171 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2172 ASSERT_TRUE(ctx);
2173
2174 // Prepare 10 test sessions.
2175 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2176 for (int i = 0; i < 10; i++) {
2177 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2178 ASSERT_TRUE(session);
2179 sessions.push_back(std::move(session));
2180 }
2181
2182 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2183
2184 // Insert all the test sessions.
2185 for (const auto &session : sessions) {
2186 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2187 }
2188
2189 // Only the last five should be in the list.
2190 ASSERT_TRUE(CacheEquals(
2191 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2192 sessions[6].get(), sessions[5].get()}));
2193
2194 // Inserting an element already in the cache should fail and leave the cache
2195 // unchanged.
2196 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2197 ASSERT_TRUE(CacheEquals(
2198 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2199 sessions[6].get(), sessions[5].get()}));
2200
2201 // Although collisions should be impossible (256-bit session IDs), the cache
2202 // must handle them gracefully.
2203 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2204 ASSERT_TRUE(collision);
2205 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2206 ASSERT_TRUE(CacheEquals(
2207 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2208 sessions[6].get(), sessions[5].get()}));
2209
2210 // Removing sessions behaves correctly.
2211 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2212 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2213 sessions[8].get(), sessions[5].get()}));
2214
2215 // Removing sessions requires an exact match.
2216 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2217 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2218
2219 // The cache remains unchanged.
2220 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2221 sessions[8].get(), sessions[5].get()}));
2222}
2223
2224static uint16_t EpochFromSequence(uint64_t seq) {
2225 return static_cast<uint16_t>(seq >> 48);
2226}
2227
David Benjamin71dfad42017-07-16 17:27:39 -04002228static const uint8_t kTestName[] = {
2229 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2230 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2231 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2232 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2233 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2234 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2235};
2236
David Benjaminc11ea9422017-08-29 16:33:21 -04002237// SSLVersionTest executes its test cases under all available protocol versions.
2238// Test cases call |Connect| to create a connection using context objects with
2239// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002240class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2241 protected:
2242 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2243
2244 void SetUp() { ResetContexts(); }
2245
2246 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2247 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2248 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2249 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2250 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2251 return nullptr;
2252 }
2253 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002254 }
David Benjamin686bb192016-05-10 15:15:41 -04002255
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002256 void ResetContexts() {
2257 ASSERT_TRUE(cert_);
2258 ASSERT_TRUE(key_);
2259 client_ctx_ = CreateContext();
2260 ASSERT_TRUE(client_ctx_);
2261 server_ctx_ = CreateContext();
2262 ASSERT_TRUE(server_ctx_);
2263 // Set up a server cert. Client certs can be set up explicitly.
2264 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002265 }
David Benjamin686bb192016-05-10 15:15:41 -04002266
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002267 bool UseCertAndKey(SSL_CTX *ctx) const {
2268 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2269 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002270 }
David Benjamin686bb192016-05-10 15:15:41 -04002271
David Benjamina8614602017-09-06 15:40:19 -04002272 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002273 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002274 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002275 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002276 }
2277
2278 uint16_t version() const { return GetParam().version; }
2279
2280 bool is_dtls() const {
2281 return GetParam().ssl_method == VersionParam::is_dtls;
2282 }
2283
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002284 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002285 bssl::UniquePtr<SSL> client_, server_;
2286 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2287 bssl::UniquePtr<X509> cert_;
2288 bssl::UniquePtr<EVP_PKEY> key_;
2289};
2290
David Benjaminbe7006a2019-04-09 18:05:02 -05002291INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2292 testing::ValuesIn(kAllVersions),
2293 [](const testing::TestParamInfo<VersionParam> &i) {
2294 return i.param.name;
2295 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002296
2297TEST_P(SSLVersionTest, SequenceNumber) {
2298 ASSERT_TRUE(Connect());
2299
David Benjamin0fef3052016-11-18 15:11:10 +09002300 // Drain any post-handshake messages to ensure there are no unread records
2301 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002302 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002303
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002304 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2305 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2306 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2307 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002308
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002309 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002310 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002311 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2312 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2313 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2314 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002315
2316 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002317 EXPECT_GT(client_write_seq, server_read_seq);
2318 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002319 } else {
2320 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002321 EXPECT_EQ(client_write_seq, server_read_seq);
2322 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002323 }
2324
2325 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002326 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002327 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2328 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002329
2330 // The client write and server read sequence numbers should have
2331 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002332 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2333 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002334}
2335
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002336TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002337 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002338 if (is_dtls()) {
2339 return;
David Benjamin686bb192016-05-10 15:15:41 -04002340 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002341 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002342
2343 // Shut down half the connection. SSL_shutdown will return 0 to signal only
2344 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002345 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002346
2347 // Reading from the server should consume the EOF.
2348 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002349 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2350 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002351
2352 // However, the server may continue to write data and then shut down the
2353 // connection.
2354 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002355 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2356 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2357 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002358
2359 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002360 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2361 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002362}
David Benjamin68f37b72016-11-18 15:14:42 +09002363
David Benjaminf0d8e222017-02-04 10:58:26 -05002364TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002365 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002366 bssl::UniquePtr<SSL_CTX> server_ctx =
2367 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002368 ASSERT_TRUE(client_ctx);
2369 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002370
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002371 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002372 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002373 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002374
2375 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002376 bssl::UniquePtr<SSL_SESSION> session1 =
2377 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002378 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002379
David Benjamina3a71e92018-06-29 13:24:45 -04002380 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002381
Steven Valdez87eab492016-06-27 16:34:59 -04002382 uint8_t *s0_bytes, *s1_bytes;
2383 size_t s0_len, s1_len;
2384
David Benjaminf0d8e222017-02-04 10:58:26 -05002385 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002386 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002387
David Benjaminf0d8e222017-02-04 10:58:26 -05002388 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002389 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002390
David Benjamin7d7554b2017-02-04 11:48:59 -05002391 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002392}
David Benjamin686bb192016-05-10 15:15:41 -04002393
David Benjaminf0d8e222017-02-04 10:58:26 -05002394static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002395 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002396 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2397 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002398
2399 // The wrapper BIOs are always equal when fds are equal, even if set
2400 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002401 if (rfd == wfd) {
2402 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002403 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002404}
2405
David Benjaminf0d8e222017-02-04 10:58:26 -05002406TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002407 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002408 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002409
2410 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002411 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002412 ASSERT_TRUE(ssl);
2413 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2414 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2415 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002416
2417 // Test setting the same FD.
2418 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002419 ASSERT_TRUE(ssl);
2420 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2421 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002422
2423 // Test setting the same FD one side at a time.
2424 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002425 ASSERT_TRUE(ssl);
2426 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2427 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2428 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002429
2430 // Test setting the same FD in the other order.
2431 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002432 ASSERT_TRUE(ssl);
2433 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2434 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2435 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002436
David Benjamin5c0fb882016-06-14 14:03:51 -04002437 // Test changing the read FD partway through.
2438 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002439 ASSERT_TRUE(ssl);
2440 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2441 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2442 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002443
2444 // Test changing the write FD partway through.
2445 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002446 ASSERT_TRUE(ssl);
2447 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2448 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2449 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002450
2451 // Test a no-op change to the read FD partway through.
2452 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002453 ASSERT_TRUE(ssl);
2454 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2455 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2456 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002457
2458 // Test a no-op change to the write FD partway through.
2459 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002460 ASSERT_TRUE(ssl);
2461 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2462 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2463 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002464
2465 // ASan builds will implicitly test that the internal |BIO| reference-counting
2466 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002467}
2468
David Benjaminf0d8e222017-02-04 10:58:26 -05002469TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002470 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002471 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002472
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002473 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2474 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002475 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002476 ASSERT_TRUE(ssl);
2477 ASSERT_TRUE(bio1);
2478 ASSERT_TRUE(bio2);
2479 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002480
2481 // SSL_set_bio takes one reference when the parameters are the same.
2482 BIO_up_ref(bio1.get());
2483 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2484
2485 // Repeating the call does nothing.
2486 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2487
2488 // It takes one reference each when the parameters are different.
2489 BIO_up_ref(bio2.get());
2490 BIO_up_ref(bio3.get());
2491 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2492
2493 // Repeating the call does nothing.
2494 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2495
2496 // It takes one reference when changing only wbio.
2497 BIO_up_ref(bio1.get());
2498 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2499
2500 // It takes one reference when changing only rbio and the two are different.
2501 BIO_up_ref(bio3.get());
2502 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2503
2504 // If setting wbio to rbio, it takes no additional references.
2505 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2506
2507 // From there, wbio may be switched to something else.
2508 BIO_up_ref(bio1.get());
2509 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2510
2511 // If setting rbio to wbio, it takes no additional references.
2512 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2513
2514 // From there, rbio may be switched to something else, but, for historical
2515 // reasons, it takes a reference to both parameters.
2516 BIO_up_ref(bio1.get());
2517 BIO_up_ref(bio2.get());
2518 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2519
2520 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2521 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002522}
2523
David Benjamin25490f22016-07-14 00:22:54 -04002524static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2525
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002526TEST_P(SSLVersionTest, GetPeerCertificate) {
2527 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002528
David Benjamin0fef3052016-11-18 15:11:10 +09002529 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002530 SSL_CTX_set_verify(client_ctx_.get(),
2531 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2532 nullptr);
2533 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2534 SSL_CTX_set_verify(server_ctx_.get(),
2535 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2536 nullptr);
2537 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002538
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002540
David Benjamin0fef3052016-11-18 15:11:10 +09002541 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002542 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2543 ASSERT_TRUE(peer);
2544 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002545
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002546 peer.reset(SSL_get_peer_certificate(client_.get()));
2547 ASSERT_TRUE(peer);
2548 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002549
David Benjamine664a532017-07-20 20:19:36 -04002550 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002551 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002552 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2553 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2554 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002555
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002556 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2557 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2558 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002559}
2560
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002561TEST_P(SSLVersionTest, NoPeerCertificate) {
2562 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2563 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2564 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002565
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002566 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002567
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002568 // Server should not see a peer certificate.
2569 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2570 ASSERT_FALSE(peer);
2571 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002572}
2573
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002574TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002575 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002576 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2577 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002578 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002579
2580 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2581 SHA256(cert_der, cert_der_len, cert_sha256);
2582
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002583 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2584
David Benjamin0fef3052016-11-18 15:11:10 +09002585 // Configure both client and server to accept any certificate, but the
2586 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002587 SSL_CTX_set_verify(client_ctx_.get(),
2588 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2589 nullptr);
2590 SSL_CTX_set_verify(server_ctx_.get(),
2591 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2592 nullptr);
2593 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2594 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2595 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002596
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002597 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002598
David Benjamin0fef3052016-11-18 15:11:10 +09002599 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002600 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2601 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002602
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002603 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002604 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002605
David Benjamin02de7bd2018-05-08 18:13:54 -04002606 const uint8_t *peer_sha256;
2607 size_t peer_sha256_len;
2608 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2609 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002610}
2611
David Benjamin737d2df2017-09-25 15:05:19 -04002612// Tests that our ClientHellos do not change unexpectedly. These are purely
2613// change detection tests. If they fail as part of an intentional ClientHello
2614// change, update the test vector.
2615TEST(SSLTest, ClientHello) {
2616 struct {
2617 uint16_t max_version;
2618 std::vector<uint8_t> expected;
2619 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002620 {TLS1_VERSION,
2621 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2625 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002626 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2627 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2628 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002629 {TLS1_1_VERSION,
2630 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2634 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002635 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2636 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2637 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002638 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002639 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002643 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002644 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002645 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2646 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2647 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2648 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2649 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2650 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002651 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2652 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002653 };
David Benjamin737d2df2017-09-25 15:05:19 -04002654
2655 for (const auto &t : kTests) {
2656 SCOPED_TRACE(t.max_version);
2657
2658 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2659 ASSERT_TRUE(ctx);
2660 // Our default cipher list varies by CPU capabilities, so manually place the
2661 // ChaCha20 ciphers in front.
2662 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002663 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2664 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2665
2666 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2667 ASSERT_TRUE(ssl);
2668 std::vector<uint8_t> client_hello;
2669 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2670
2671 // Zero the client_random.
2672 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2673 1 + 3 + // handshake message header
2674 2; // client_version
2675 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2676 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2677
2678 if (client_hello != t.expected) {
2679 ADD_FAILURE() << "ClientHellos did not match.";
2680 // Print the value manually so it is easier to update the test vector.
2681 for (size_t i = 0; i < client_hello.size(); i += 12) {
2682 printf(" %c", i == 0 ? '{' : ' ');
2683 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2684 if (j > i) {
2685 printf(" ");
2686 }
2687 printf("0x%02x", client_hello[j]);
2688 if (j < client_hello.size() - 1) {
2689 printf(",");
2690 }
2691 }
2692 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002693 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002694 }
2695 printf("\n");
2696 }
2697 }
David Benjaminafc64de2016-07-19 17:12:41 +02002698 }
David Benjaminafc64de2016-07-19 17:12:41 +02002699}
2700
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002701static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002702
2703static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2704 // Save the most recent session.
2705 g_last_session.reset(session);
2706 return 1;
2707}
2708
David Benjamina8614602017-09-06 15:40:19 -04002709static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2710 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2711 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002712 g_last_session = nullptr;
2713 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2714
2715 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002716 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002717 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002718 config) ||
2719 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002720 fprintf(stderr, "Failed to connect client and server.\n");
2721 return nullptr;
2722 }
2723
David Benjamina20e5352016-08-02 19:09:41 -04002724 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2725
2726 if (!g_last_session) {
2727 fprintf(stderr, "Client did not receive a session.\n");
2728 return nullptr;
2729 }
2730 return std::move(g_last_session);
2731}
2732
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002733static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2734 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002735 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002736 ClientConfig config;
2737 config.session = session;
2738 EXPECT_TRUE(
2739 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002740
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002741 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002742
2743 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002745}
2746
David Benjamin3c51d9b2016-11-01 17:50:42 -04002747static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2748 SSL_CTX *server_ctx,
2749 SSL_SESSION *session) {
2750 g_last_session = nullptr;
2751 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2752
2753 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002754 ClientConfig config;
2755 config.session = session;
2756 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002757 config) ||
2758 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002759 fprintf(stderr, "Failed to connect client and server.\n");
2760 return nullptr;
2761 }
2762
2763 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2764 fprintf(stderr, "Client and server were inconsistent.\n");
2765 return nullptr;
2766 }
2767
2768 if (!SSL_session_reused(client.get())) {
2769 fprintf(stderr, "Session was not reused.\n");
2770 return nullptr;
2771 }
2772
David Benjamin3c51d9b2016-11-01 17:50:42 -04002773 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2774
2775 if (!g_last_session) {
2776 fprintf(stderr, "Client did not receive a renewed session.\n");
2777 return nullptr;
2778 }
2779 return std::move(g_last_session);
2780}
2781
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002782static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002783 bool changed) {
2784 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002785 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002786 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2787 if (changed) {
2788 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2789 } else {
2790 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002791 }
2792 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002793}
2794
David Benjamina933c382016-10-28 00:10:03 -04002795static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2796 static const uint8_t kContext[] = {3};
2797
2798 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2799 return SSL_TLSEXT_ERR_ALERT_FATAL;
2800 }
2801
2802 return SSL_TLSEXT_ERR_OK;
2803}
2804
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002805TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002806 static const uint8_t kContext1[] = {1};
2807 static const uint8_t kContext2[] = {2};
2808
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002809 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2810 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002811
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002812 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2813 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002814
David Benjamin0fef3052016-11-18 15:11:10 +09002815 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002816 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2817 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002818
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002819 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2820 session.get(),
2821 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002822
David Benjamin0fef3052016-11-18 15:11:10 +09002823 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002824 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2825 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002826
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002827 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2828 session.get(),
2829 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002830
David Benjamin0fef3052016-11-18 15:11:10 +09002831 // Change the session ID context back and install an SNI callback to switch
2832 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002833 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2834 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002835
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002836 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002837 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002838
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002839 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2840 session.get(),
2841 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002842
David Benjamin0fef3052016-11-18 15:11:10 +09002843 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002844 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002845 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002846 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002847 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2848 static const uint8_t kContext[] = {3};
2849
2850 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2851 sizeof(kContext))) {
2852 return ssl_select_cert_error;
2853 }
2854
2855 return ssl_select_cert_success;
2856 });
David Benjamina933c382016-10-28 00:10:03 -04002857
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002858 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2859 session.get(),
2860 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002861}
2862
David Benjamin721e8b72016-08-03 13:13:17 -04002863static timeval g_current_time;
2864
2865static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2866 *out_clock = g_current_time;
2867}
2868
David Benjamin17b30832017-01-28 14:00:32 -05002869static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2870 out_clock->tv_sec = 1000;
2871 out_clock->tv_usec = 0;
2872}
2873
David Benjamin3c51d9b2016-11-01 17:50:42 -04002874static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2875 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2876 int encrypt) {
2877 static const uint8_t kZeros[16] = {0};
2878
2879 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002880 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002881 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002882 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002883 return 0;
2884 }
2885
2886 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2887 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2888 return -1;
2889 }
2890
2891 // Returning two from the callback in decrypt mode renews the
2892 // session in TLS 1.2 and below.
2893 return encrypt ? 1 : 2;
2894}
2895
David Benjamin123db572016-11-03 16:59:25 -04002896static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002897 const uint8_t *ticket;
2898 size_t ticket_len;
2899 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2900 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002901 return false;
2902 }
2903
David Benjaminaaef8332018-06-29 16:45:49 -04002904 const uint8_t *ciphertext = ticket + 16 + 16;
2905 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002906 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2907
David Benjamin9b63f292016-11-15 00:44:05 -05002908#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2909 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002910 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002911#else
2912 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002913 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002914 bssl::ScopedEVP_CIPHER_CTX ctx;
2915 int len1, len2;
2916 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2917 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2918 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2919 return false;
2920 }
2921
2922 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002923#endif
David Benjamin123db572016-11-03 16:59:25 -04002924
Adam Langley46db7af2017-02-01 15:49:37 -08002925 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2926 if (!ssl_ctx) {
2927 return false;
2928 }
David Benjamin123db572016-11-03 16:59:25 -04002929 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002930 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002931 if (!server_session) {
2932 return false;
2933 }
2934
David Benjaminaaef8332018-06-29 16:45:49 -04002935 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002936 return true;
2937}
2938
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002939TEST_P(SSLVersionTest, SessionTimeout) {
2940 for (bool server_test : {false, true}) {
2941 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002942
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002943 ResetContexts();
2944 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2945 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2946
David Benjamin17b30832017-01-28 14:00:32 -05002947 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002948 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002949
David Benjamin17b30832017-01-28 14:00:32 -05002950 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2951 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002952 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002953 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2954 : SSL_DEFAULT_SESSION_TIMEOUT;
2955
David Benjamin17b30832017-01-28 14:00:32 -05002956 // Both client and server must enforce session timeouts. We configure the
2957 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002958 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002959 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2960 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002961 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002962 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2963 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002964 }
2965
2966 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002967 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002968
2969 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002970 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2971 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002972
2973 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002974 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002975
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002976 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2977 session.get(),
2978 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002979
2980 // Advance the clock one more second.
2981 g_current_time.tv_sec++;
2982
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002983 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2984 session.get(),
2985 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002986
2987 // Rewind the clock to before the session was minted.
2988 g_current_time.tv_sec = kStartTime - 1;
2989
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002990 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2991 session.get(),
2992 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002993
David Benjamin0fef3052016-11-18 15:11:10 +09002994 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002995 time_t new_start_time = kStartTime + timeout - 10;
2996 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002997 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2998 client_ctx_.get(), server_ctx_.get(), session.get());
2999 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09003000
3001 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003002 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003003
3004 // Check the sessions have timestamps measured from issuance.
3005 long session_time = 0;
3006 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003007 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003008 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003009 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003010 }
David Benjamin721e8b72016-08-03 13:13:17 -04003011
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003012 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003013
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003014 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003015 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3016 // lifetime TLS 1.3.
3017 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003018 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3019 new_session.get(),
3020 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003021
David Benjamin17b30832017-01-28 14:00:32 -05003022 // The new session expires after the new timeout.
3023 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003024 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3025 new_session.get(),
3026 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003027
3028 // Renew the session until it begins just past the auth timeout.
3029 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3030 while (new_start_time < auth_end_time - 1000) {
3031 // Get as close as possible to target start time.
3032 new_start_time =
3033 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3034 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003035 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003036 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003037 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003038 }
3039
3040 // Now the session's lifetime is bound by the auth timeout.
3041 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003042 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3043 new_session.get(),
3044 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003045
3046 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003047 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3048 new_session.get(),
3049 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003050 } else {
3051 // The new session is usable just before the old expiration.
3052 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003053 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3054 new_session.get(),
3055 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003056
3057 // Renewal does not extend the lifetime, so it is not usable beyond the
3058 // old expiration.
3059 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003060 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3061 new_session.get(),
3062 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003063 }
David Benjamin721e8b72016-08-03 13:13:17 -04003064 }
David Benjamin721e8b72016-08-03 13:13:17 -04003065}
3066
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003067TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003068 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3069 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003070 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003071 kTicketKeyLen));
3072 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3073}
3074
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003075TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003076 static const time_t kStartTime = 1001;
3077 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003078
David Benjaminc11ea9422017-08-29 16:33:21 -04003079 // We use session reuse as a proxy for ticket decryption success, hence
3080 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003081 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3082 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003083 std::numeric_limits<uint32_t>::max());
3084
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003085 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3086 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003087
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003088 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3089 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003090
David Benjamin1f0d54b2018-08-09 16:19:13 -05003091 // Initialize ticket_key with the current key and check that it was
3092 // initialized to something, not all zeros.
3093 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003094 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3095 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003096
David Benjaminc11ea9422017-08-29 16:33:21 -04003097 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003098 bssl::UniquePtr<SSL> client, server;
3099 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003100 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003101 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003102 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003103 session.get(), true /* reused */));
3104
David Benjaminc11ea9422017-08-29 16:33:21 -04003105 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003106 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003107 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003108 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003109 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003110 false /* NOT changed */));
3111
David Benjaminc11ea9422017-08-29 16:33:21 -04003112 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003113 g_current_time.tv_sec += 1;
3114 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003115 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3116 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3117 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003118
David Benjaminc11ea9422017-08-29 16:33:21 -04003119 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003120 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003121 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003122 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003123 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003124 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003125 false /* NOT changed */));
3126
David Benjaminc11ea9422017-08-29 16:33:21 -04003127 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003128 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003129 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003130 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003131 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3132 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003133
David Benjaminc11ea9422017-08-29 16:33:21 -04003134 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003135 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003136 new_session.get(), true /* reused */));
3137}
3138
David Benjamin0fc37ef2016-08-17 15:29:46 -04003139static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003140 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003141 SSL_set_SSL_CTX(ssl, ctx);
3142 return SSL_TLSEXT_ERR_OK;
3143}
3144
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003145TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003146 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003147 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003148 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003149 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003150
David Benjamin0fef3052016-11-18 15:11:10 +09003151 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3152 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003153
David Benjamin83a32122017-02-14 18:34:54 -05003154 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3155 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3156
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003157 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3158 ASSERT_TRUE(server_ctx2);
3159 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3160 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3161 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3162 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3163 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3164 sizeof(kOCSPResponse)));
3165 // Historically signing preferences would be lost in some cases with the
3166 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3167 // this doesn't happen when |version| is TLS 1.2, configure the private
3168 // key to only sign SHA-256.
3169 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3170 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003171
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003172 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3173 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003174
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003175 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3176 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003177
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003178 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003179
David Benjamin0fef3052016-11-18 15:11:10 +09003180 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003181 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3182 ASSERT_TRUE(peer);
3183 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003184
David Benjamin83a32122017-02-14 18:34:54 -05003185 // The client should have received |server_ctx2|'s SCT list.
3186 const uint8_t *data;
3187 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003188 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3189 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003190
3191 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003192 SSL_get0_ocsp_response(client_.get(), &data, &len);
3193 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003194}
3195
David Benjaminf0d8e222017-02-04 10:58:26 -05003196// Test that the early callback can swap the maximum version.
3197TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003198 bssl::UniquePtr<SSL_CTX> server_ctx =
3199 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003200 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003201 ASSERT_TRUE(server_ctx);
3202 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003203 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3204 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003205
David Benjaminf0d8e222017-02-04 10:58:26 -05003206 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003207 server_ctx.get(),
3208 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003209 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003210 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003211 }
3212
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003213 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003214 });
David Benjamin99620572016-08-30 00:35:36 -04003215
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003216 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003217 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003218 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003219 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003220}
3221
David Benjaminf0d8e222017-02-04 10:58:26 -05003222TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003223 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003224 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003225
David Benjaminf0d8e222017-02-04 10:58:26 -05003226 // Set valid TLS versions.
3227 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3228 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3229 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3230 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003231
David Benjaminf0d8e222017-02-04 10:58:26 -05003232 // Invalid TLS versions are rejected.
3233 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3234 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3235 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3236 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3237 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3238 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003239
David Benjaminf0d8e222017-02-04 10:58:26 -05003240 // Zero is the default version.
3241 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003242 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003243 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003244 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003245
David Benjamin9bb15f52018-06-26 00:07:40 -04003246 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003247 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003248 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04003249
David Benjamin9bb15f52018-06-26 00:07:40 -04003250 // SSL 3.0 is not available.
3251 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3252
David Benjamin2dc02042016-09-19 19:57:37 -04003253 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003254 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003255
David Benjaminf0d8e222017-02-04 10:58:26 -05003256 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3257 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
3258 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3259 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003260
David Benjaminf0d8e222017-02-04 10:58:26 -05003261 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3262 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3263 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3264 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3265 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3266 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3267 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3268 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003269
David Benjaminf0d8e222017-02-04 10:58:26 -05003270 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003271 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003272 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003273 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003274}
3275
David Benjamin458334a2016-12-15 13:53:25 -05003276static const char *GetVersionName(uint16_t version) {
3277 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003278 case TLS1_VERSION:
3279 return "TLSv1";
3280 case TLS1_1_VERSION:
3281 return "TLSv1.1";
3282 case TLS1_2_VERSION:
3283 return "TLSv1.2";
3284 case TLS1_3_VERSION:
3285 return "TLSv1.3";
3286 case DTLS1_VERSION:
3287 return "DTLSv1";
3288 case DTLS1_2_VERSION:
3289 return "DTLSv1.2";
3290 default:
3291 return "???";
3292 }
3293}
3294
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003295TEST_P(SSLVersionTest, Version) {
3296 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003297
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003298 EXPECT_EQ(SSL_version(client_.get()), version());
3299 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003300
David Benjamin458334a2016-12-15 13:53:25 -05003301 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003302 const char *version_name = GetVersionName(version());
3303 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3304 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003305
3306 // Test SSL_SESSION reports the same name.
3307 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003308 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003309 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003310 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3311 EXPECT_EQ(strcmp(version_name, client_name), 0);
3312 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003313}
3314
David Benjamin9ef31f02016-10-31 18:01:13 -04003315// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3316// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003317TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003318 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3319
David Benjamin9ef31f02016-10-31 18:01:13 -04003320 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003321 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3322 sizeof(kALPNProtos)),
3323 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003324
3325 // The ALPN callback does not fail the handshake on error, so have the
3326 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003327 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003328 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003329 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003330 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3331 unsigned in_len, void *arg) -> int {
3332 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3333 if (SSL_get_pending_cipher(ssl) != nullptr &&
3334 SSL_version(ssl) == state->first) {
3335 state->second = true;
3336 }
3337 return SSL_TLSEXT_ERR_NOACK;
3338 },
3339 &callback_state);
3340
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003341 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003342
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003343 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003344}
3345
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003346TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003347 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3348 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003349 if (version() == TLS1_3_VERSION) {
3350 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003351 }
3352
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003353 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003354 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003355
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003356 EXPECT_FALSE(SSL_session_reused(client_.get()));
3357 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003358
3359 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003360 ASSERT_TRUE(SSL_clear(client_.get()));
3361 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003362
3363 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003364 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003365
3366 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003367 EXPECT_TRUE(SSL_session_reused(client_.get()));
3368 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003369}
3370
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003371TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3372 shed_handshake_config_ = false;
3373 ASSERT_TRUE(Connect());
3374 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3375
3376 // Reset everything.
3377 ASSERT_TRUE(SSL_clear(client_.get()));
3378 ASSERT_TRUE(SSL_clear(server_.get()));
3379
3380 // Now enable shedding, and connect a second time.
3381 shed_handshake_config_ = true;
3382 ASSERT_TRUE(Connect());
3383 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3384
3385 // |SSL_clear| should now fail.
3386 ASSERT_FALSE(SSL_clear(client_.get()));
3387 ASSERT_FALSE(SSL_clear(server_.get()));
3388}
3389
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003390static bool ChainsEqual(STACK_OF(X509) * chain,
3391 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003392 if (sk_X509_num(chain) != expected.size()) {
3393 return false;
3394 }
3395
3396 for (size_t i = 0; i < expected.size(); i++) {
3397 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3398 return false;
3399 }
3400 }
3401
3402 return true;
3403}
3404
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003405TEST_P(SSLVersionTest, AutoChain) {
3406 cert_ = GetChainTestCertificate();
3407 ASSERT_TRUE(cert_);
3408 key_ = GetChainTestKey();
3409 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003410 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003411 ASSERT_TRUE(intermediate);
3412
3413 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3414 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003415
3416 // Configure both client and server to accept any certificate. Add
3417 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003418 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3419 intermediate.get()));
3420 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3421 intermediate.get()));
3422 SSL_CTX_set_verify(client_ctx_.get(),
3423 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3424 nullptr);
3425 SSL_CTX_set_verify(server_ctx_.get(),
3426 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3427 nullptr);
3428 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3429 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003430
3431 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003432 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003433
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003434 EXPECT_TRUE(
3435 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3436 EXPECT_TRUE(
3437 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003438
3439 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003440 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3441 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3442 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003444 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3445 {cert_.get(), intermediate.get()}));
3446 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3447 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003448
3449 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003450 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3451 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3452 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003453
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003454 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3455 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003456
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003457 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3458 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003459}
3460
David Benjamin48063c22017-01-01 23:56:36 -05003461static bool ExpectBadWriteRetry() {
3462 int err = ERR_get_error();
3463 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3464 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3465 char buf[ERR_ERROR_STRING_BUF_LEN];
3466 ERR_error_string_n(err, buf, sizeof(buf));
3467 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3468 return false;
3469 }
3470
3471 if (ERR_peek_error() != 0) {
3472 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3473 return false;
3474 }
3475
3476 return true;
3477}
3478
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003479TEST_P(SSLVersionTest, SSLWriteRetry) {
3480 if (is_dtls()) {
3481 return;
David Benjamin48063c22017-01-01 23:56:36 -05003482 }
3483
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003484 for (bool enable_partial_write : {false, true}) {
3485 SCOPED_TRACE(enable_partial_write);
3486
David Benjamin48063c22017-01-01 23:56:36 -05003487 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003488 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3489
3490 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003491
3492 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003493 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003494 }
3495
3496 // Write without reading until the buffer is full and we have an unfinished
3497 // write. Keep a count so we may reread it again later. "hello!" will be
3498 // written in two chunks, "hello" and "!".
3499 char data[] = "hello!";
3500 static const int kChunkLen = 5; // The length of "hello".
3501 unsigned count = 0;
3502 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003503 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003504 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003505 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3506 break;
David Benjamin48063c22017-01-01 23:56:36 -05003507 }
3508
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003509 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003510
3511 count++;
3512 }
3513
3514 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003515 ASSERT_EQ(
3516 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3517 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003518
3519 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003520 ASSERT_EQ(SSL_get_error(client_.get(),
3521 SSL_write(client_.get(), data, kChunkLen - 1)),
3522 SSL_ERROR_SSL);
3523 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003524
3525 // Retrying with a different buffer pointer is not legal.
3526 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003527 ASSERT_EQ(SSL_get_error(client_.get(),
3528 SSL_write(client_.get(), data2, kChunkLen)),
3529 SSL_ERROR_SSL);
3530 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003531
3532 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003533 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3534 ASSERT_EQ(SSL_get_error(client_.get(),
3535 SSL_write(client_.get(), data2, kChunkLen)),
3536 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003537
3538 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003539 ASSERT_EQ(SSL_get_error(client_.get(),
3540 SSL_write(client_.get(), data2, kChunkLen - 1)),
3541 SSL_ERROR_SSL);
3542 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003543
3544 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003545 ASSERT_EQ(SSL_get_error(client_.get(),
3546 SSL_write(client_.get(), data, kChunkLen + 1)),
3547 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003548
3549 // Drain the buffer.
3550 char buf[20];
3551 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003552 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3553 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003554 }
3555
3556 // Now that there is space, a retry with a larger buffer should flush the
3557 // pending record, skip over that many bytes of input (on assumption they
3558 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3559 // is set, this will complete in two steps.
3560 char data3[] = "_____!";
3561 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003562 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3563 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3564 } else {
3565 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003566 }
3567
3568 // Check the last write was correct. The data will be spread over two
3569 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003570 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3571 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3572 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3573 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003574 }
David Benjamin48063c22017-01-01 23:56:36 -05003575}
3576
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003577TEST_P(SSLVersionTest, RecordCallback) {
3578 for (bool test_server : {true, false}) {
3579 SCOPED_TRACE(test_server);
3580 ResetContexts();
David Benjamin5df5be1a2017-06-22 19:43:11 -04003581
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003582 bool read_seen = false;
3583 bool write_seen = false;
3584 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3585 size_t len, SSL *ssl) {
3586 if (cb_type != SSL3_RT_HEADER) {
3587 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003588 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003589
3590 // The callback does not report a version for records.
3591 EXPECT_EQ(0, cb_version);
3592
3593 if (is_write) {
3594 write_seen = true;
3595 } else {
3596 read_seen = true;
3597 }
3598
3599 // Sanity-check that the record header is plausible.
3600 CBS cbs;
3601 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3602 uint8_t type;
3603 uint16_t record_version, length;
3604 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3605 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003606 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003607 if (is_dtls()) {
3608 uint16_t epoch;
3609 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3610 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3611 ASSERT_TRUE(CBS_skip(&cbs, 6));
3612 }
3613 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3614 EXPECT_EQ(0u, CBS_len(&cbs));
3615 };
3616 using CallbackType = decltype(cb);
3617 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3618 SSL_CTX_set_msg_callback(
3619 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3620 size_t len, SSL *ssl, void *arg) {
3621 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3622 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3623 });
3624 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3625
3626 ASSERT_TRUE(Connect());
3627
3628 EXPECT_TRUE(read_seen);
3629 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003630 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003631}
3632
David Benjamina8614602017-09-06 15:40:19 -04003633TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003634 ClientConfig config;
3635 config.servername = "host1";
3636
3637 SSL_CTX_set_tlsext_servername_callback(
3638 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3639 // During the handshake, |SSL_get_servername| must match |config|.
3640 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3641 EXPECT_STREQ(config_p->servername.c_str(),
3642 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3643 return SSL_TLSEXT_ERR_OK;
3644 });
3645 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3646
3647 ASSERT_TRUE(Connect(config));
3648 // After the handshake, it must also be available.
3649 EXPECT_STREQ(config.servername.c_str(),
3650 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3651
3652 // Establish a session under host1.
3653 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3654 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3655 bssl::UniquePtr<SSL_SESSION> session =
3656 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3657
3658 // If the client resumes a session with a different name, |SSL_get_servername|
3659 // must return the new name.
3660 ASSERT_TRUE(session);
3661 config.session = session.get();
3662 config.servername = "host2";
3663 ASSERT_TRUE(Connect(config));
3664 EXPECT_STREQ(config.servername.c_str(),
3665 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3666}
3667
David Benjamin3d8f0802017-09-06 16:12:52 -04003668// Test that session cache mode bits are honored in the client session callback.
3669TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3670 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3671 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3672
3673 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3674 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3675
3676 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3677 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3678}
3679
Steven Valdez777a2392019-02-21 11:30:47 -05003680// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3681// NewSessionTickets are written post-handshake. Servers that block
3682// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3683// the buffer. Test that we do not do this.
3684TEST_P(SSLVersionTest, SmallBuffer) {
3685 // DTLS is a datagram protocol and requires packet-sized buffers.
3686 if (is_dtls()) {
3687 return;
3688 }
3689
3690 // Test both flushing NewSessionTickets with a zero-sized write and
3691 // non-zero-sized write.
3692 for (bool use_zero_write : {false, true}) {
3693 SCOPED_TRACE(use_zero_write);
3694
3695 g_last_session = nullptr;
3696 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3697 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3698
3699 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3700 server(SSL_new(server_ctx_.get()));
3701 ASSERT_TRUE(client);
3702 ASSERT_TRUE(server);
3703 SSL_set_connect_state(client.get());
3704 SSL_set_accept_state(server.get());
3705
3706 // Use a tiny buffer.
3707 BIO *bio1, *bio2;
3708 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3709
3710 // SSL_set_bio takes ownership.
3711 SSL_set_bio(client.get(), bio1, bio1);
3712 SSL_set_bio(server.get(), bio2, bio2);
3713
3714 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3715 if (version() >= TLS1_3_VERSION) {
3716 // The post-handshake ticket should not have been processed yet.
3717 EXPECT_FALSE(g_last_session);
3718 }
3719
3720 if (use_zero_write) {
3721 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3722 EXPECT_TRUE(g_last_session);
3723 }
3724
3725 // Send some data from server to client. If |use_zero_write| is false, this
3726 // will also flush the NewSessionTickets.
3727 static const char kMessage[] = "hello world";
3728 char buf[sizeof(kMessage)];
3729 for (;;) {
3730 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3731 int server_err = SSL_get_error(server.get(), server_ret);
3732 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3733 int client_err = SSL_get_error(client.get(), client_ret);
3734
3735 // The server will write a single record, so every iteration should see
3736 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3737 // iteration, where both will complete.
3738 if (server_ret > 0) {
3739 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3740 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3741 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3742 break;
3743 }
3744
3745 ASSERT_EQ(server_ret, -1);
3746 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3747 ASSERT_EQ(client_ret, -1);
3748 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3749 }
3750
3751 // The NewSessionTickets should have been flushed and processed.
3752 EXPECT_TRUE(g_last_session);
3753 }
3754}
3755
Adam Langleye1e78132017-01-31 15:24:31 -08003756TEST(SSLTest, AddChainCertHack) {
3757 // Ensure that we don't accidently break the hack that we have in place to
3758 // keep curl and serf happy when they use an |X509| even after transfering
3759 // ownership.
3760
3761 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3762 ASSERT_TRUE(ctx);
3763 X509 *cert = GetTestCertificate().release();
3764 ASSERT_TRUE(cert);
3765 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3766
3767 // This should not trigger a use-after-free.
3768 X509_cmp(cert, cert);
3769}
3770
David Benjaminb2ff2622017-02-03 17:06:18 -05003771TEST(SSLTest, GetCertificate) {
3772 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3773 ASSERT_TRUE(ctx);
3774 bssl::UniquePtr<X509> cert = GetTestCertificate();
3775 ASSERT_TRUE(cert);
3776 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3777 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3778 ASSERT_TRUE(ssl);
3779
3780 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3781 ASSERT_TRUE(cert2);
3782 X509 *cert3 = SSL_get_certificate(ssl.get());
3783 ASSERT_TRUE(cert3);
3784
3785 // The old and new certificates must be identical.
3786 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3787 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3788
3789 uint8_t *der = nullptr;
3790 long der_len = i2d_X509(cert.get(), &der);
3791 ASSERT_LT(0, der_len);
3792 bssl::UniquePtr<uint8_t> free_der(der);
3793
3794 uint8_t *der2 = nullptr;
3795 long der2_len = i2d_X509(cert2, &der2);
3796 ASSERT_LT(0, der2_len);
3797 bssl::UniquePtr<uint8_t> free_der2(der2);
3798
3799 uint8_t *der3 = nullptr;
3800 long der3_len = i2d_X509(cert3, &der3);
3801 ASSERT_LT(0, der3_len);
3802 bssl::UniquePtr<uint8_t> free_der3(der3);
3803
3804 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003805 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3806 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003807}
3808
Adam Langleyd04ca952017-02-28 11:26:51 -08003809TEST(SSLTest, SetChainAndKeyMismatch) {
3810 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3811 ASSERT_TRUE(ctx);
3812
3813 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3814 ASSERT_TRUE(key);
3815 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3816 ASSERT_TRUE(leaf);
3817 std::vector<CRYPTO_BUFFER*> chain = {
3818 leaf.get(),
3819 };
3820
3821 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3822 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3823 key.get(), nullptr));
3824 ERR_clear_error();
3825}
3826
3827TEST(SSLTest, SetChainAndKey) {
3828 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3829 ASSERT_TRUE(client_ctx);
3830 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3831 ASSERT_TRUE(server_ctx);
3832
Adam Langley964256d2020-03-19 11:57:12 -07003833 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
3834
Adam Langleyd04ca952017-02-28 11:26:51 -08003835 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3836 ASSERT_TRUE(key);
3837 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3838 ASSERT_TRUE(leaf);
3839 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3840 GetChainTestIntermediateBuffer();
3841 ASSERT_TRUE(intermediate);
3842 std::vector<CRYPTO_BUFFER*> chain = {
3843 leaf.get(), intermediate.get(),
3844 };
3845 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3846 chain.size(), key.get(), nullptr));
3847
Adam Langley964256d2020-03-19 11:57:12 -07003848 ASSERT_EQ(chain.size(),
3849 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
3850
David Benjamin3a1dd462017-07-11 16:13:10 -04003851 SSL_CTX_set_custom_verify(
3852 client_ctx.get(), SSL_VERIFY_PEER,
3853 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3854 return ssl_verify_ok;
3855 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003856
3857 bssl::UniquePtr<SSL> client, server;
3858 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003859 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003860}
3861
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003862TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3863 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3864 ASSERT_TRUE(client_ctx);
3865 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3866 ASSERT_TRUE(server_ctx);
3867
3868 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3869 ASSERT_TRUE(key);
3870 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3871 ASSERT_TRUE(leaf);
3872 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3873 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3874 chain.size(), key.get(), nullptr));
3875
3876 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3877 // configuration, certificate verification should fail.
3878 bssl::UniquePtr<SSL> client, server;
3879 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3880 server_ctx.get()));
3881
3882 // Whereas with a verifier, the connection should succeed.
3883 SSL_CTX_set_custom_verify(
3884 client_ctx.get(), SSL_VERIFY_PEER,
3885 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3886 return ssl_verify_ok;
3887 });
3888 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3889 server_ctx.get()));
3890}
3891
3892TEST(SSLTest, CustomVerify) {
3893 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3894 ASSERT_TRUE(client_ctx);
3895 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3896 ASSERT_TRUE(server_ctx);
3897
3898 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3899 ASSERT_TRUE(key);
3900 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3901 ASSERT_TRUE(leaf);
3902 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3903 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3904 chain.size(), key.get(), nullptr));
3905
3906 SSL_CTX_set_custom_verify(
3907 client_ctx.get(), SSL_VERIFY_PEER,
3908 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3909 return ssl_verify_ok;
3910 });
3911
3912 bssl::UniquePtr<SSL> client, server;
3913 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3914 server_ctx.get()));
3915
3916 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3917 // connection.
3918 SSL_CTX_set_custom_verify(
3919 client_ctx.get(), SSL_VERIFY_PEER,
3920 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3921 return ssl_verify_invalid;
3922 });
3923
3924 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3925 server_ctx.get()));
3926
3927 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3928 // connection.
3929 SSL_CTX_set_custom_verify(
3930 client_ctx.get(), SSL_VERIFY_NONE,
3931 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3932 return ssl_verify_invalid;
3933 });
3934
3935 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3936 server_ctx.get()));
3937}
3938
David Benjamin71dfad42017-07-16 17:27:39 -04003939TEST(SSLTest, ClientCABuffers) {
3940 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3941 ASSERT_TRUE(client_ctx);
3942 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3943 ASSERT_TRUE(server_ctx);
3944
3945 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3946 ASSERT_TRUE(key);
3947 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3948 ASSERT_TRUE(leaf);
3949 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3950 GetChainTestIntermediateBuffer();
3951 ASSERT_TRUE(intermediate);
3952 std::vector<CRYPTO_BUFFER *> chain = {
3953 leaf.get(),
3954 intermediate.get(),
3955 };
3956 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3957 chain.size(), key.get(), nullptr));
3958
3959 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3960 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3961 ASSERT_TRUE(ca_name);
3962 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3963 sk_CRYPTO_BUFFER_new_null());
3964 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003965 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003966 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3967
3968 // Configure client and server to accept all certificates.
3969 SSL_CTX_set_custom_verify(
3970 client_ctx.get(), SSL_VERIFY_PEER,
3971 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3972 return ssl_verify_ok;
3973 });
3974 SSL_CTX_set_custom_verify(
3975 server_ctx.get(), SSL_VERIFY_PEER,
3976 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3977 return ssl_verify_ok;
3978 });
3979
3980 bool cert_cb_called = false;
3981 SSL_CTX_set_cert_cb(
3982 client_ctx.get(),
3983 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003984 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003985 SSL_get0_server_requested_CAs(ssl);
3986 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3987 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3988 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3989 CRYPTO_BUFFER_len(peer_name)));
3990 *reinterpret_cast<bool *>(arg) = true;
3991 return 1;
3992 },
3993 &cert_cb_called);
3994
3995 bssl::UniquePtr<SSL> client, server;
3996 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003997 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003998 EXPECT_TRUE(cert_cb_called);
3999}
4000
David Benjamin91222b82017-03-09 20:10:56 -05004001// Configuring the empty cipher list, though an error, should still modify the
4002// configuration.
4003TEST(SSLTest, EmptyCipherList) {
4004 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4005 ASSERT_TRUE(ctx);
4006
4007 // Initially, the cipher list is not empty.
4008 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4009
4010 // Configuring the empty cipher list fails.
4011 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4012 ERR_clear_error();
4013
4014 // But the cipher list is still updated to empty.
4015 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4016}
4017
Adam Langley4c341d02017-03-08 19:33:21 -08004018// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4019// test |SSL_TICKET_AEAD_METHOD| can fail.
4020enum ssl_test_ticket_aead_failure_mode {
4021 ssl_test_ticket_aead_ok = 0,
4022 ssl_test_ticket_aead_seal_fail,
4023 ssl_test_ticket_aead_open_soft_fail,
4024 ssl_test_ticket_aead_open_hard_fail,
4025};
4026
4027struct ssl_test_ticket_aead_state {
4028 unsigned retry_count;
4029 ssl_test_ticket_aead_failure_mode failure_mode;
4030};
4031
4032static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4033 const CRYPTO_EX_DATA *from,
4034 void **from_d, int index,
4035 long argl, void *argp) {
4036 abort();
4037}
4038
4039static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4040 CRYPTO_EX_DATA *ad, int index,
4041 long argl, void *argp) {
4042 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4043 if (state == nullptr) {
4044 return;
4045 }
4046
4047 OPENSSL_free(state);
4048}
4049
4050static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4051static int g_ssl_test_ticket_aead_ex_index;
4052
4053static int ssl_test_ticket_aead_get_ex_index() {
4054 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4055 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4056 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4057 ssl_test_ticket_aead_ex_index_free);
4058 });
4059 return g_ssl_test_ticket_aead_ex_index;
4060}
4061
4062static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4063 return 1;
4064}
4065
4066static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4067 size_t max_out_len, const uint8_t *in,
4068 size_t in_len) {
4069 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4070 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4071
4072 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4073 max_out_len < in_len + 1) {
4074 return 0;
4075 }
4076
4077 OPENSSL_memmove(out, in, in_len);
4078 out[in_len] = 0xff;
4079 *out_len = in_len + 1;
4080
4081 return 1;
4082}
4083
4084static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4085 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4086 const uint8_t *in, size_t in_len) {
4087 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4088 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4089
4090 if (state->retry_count > 0) {
4091 state->retry_count--;
4092 return ssl_ticket_aead_retry;
4093 }
4094
4095 switch (state->failure_mode) {
4096 case ssl_test_ticket_aead_ok:
4097 break;
4098 case ssl_test_ticket_aead_seal_fail:
4099 // If |seal| failed then there shouldn't be any ticket to try and
4100 // decrypt.
4101 abort();
4102 break;
4103 case ssl_test_ticket_aead_open_soft_fail:
4104 return ssl_ticket_aead_ignore_ticket;
4105 case ssl_test_ticket_aead_open_hard_fail:
4106 return ssl_ticket_aead_error;
4107 }
4108
4109 if (in_len == 0 || in[in_len - 1] != 0xff) {
4110 return ssl_ticket_aead_ignore_ticket;
4111 }
4112
4113 if (max_out_len < in_len - 1) {
4114 return ssl_ticket_aead_error;
4115 }
4116
4117 OPENSSL_memmove(out, in, in_len - 1);
4118 *out_len = in_len - 1;
4119 return ssl_ticket_aead_success;
4120}
4121
4122static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4123 ssl_test_ticket_aead_max_overhead,
4124 ssl_test_ticket_aead_seal,
4125 ssl_test_ticket_aead_open,
4126};
4127
4128static void ConnectClientAndServerWithTicketMethod(
4129 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4130 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4131 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4132 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4133 ASSERT_TRUE(client);
4134 ASSERT_TRUE(server);
4135 SSL_set_connect_state(client.get());
4136 SSL_set_accept_state(server.get());
4137
4138 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4139 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4140 ASSERT_TRUE(state);
4141 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4142 state->retry_count = retry_count;
4143 state->failure_mode = failure_mode;
4144
4145 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4146 state));
4147
4148 SSL_set_session(client.get(), session);
4149
4150 BIO *bio1, *bio2;
4151 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4152
4153 // SSL_set_bio takes ownership.
4154 SSL_set_bio(client.get(), bio1, bio1);
4155 SSL_set_bio(server.get(), bio2, bio2);
4156
4157 if (CompleteHandshakes(client.get(), server.get())) {
4158 *out_client = std::move(client);
4159 *out_server = std::move(server);
4160 } else {
4161 out_client->reset();
4162 out_server->reset();
4163 }
4164}
4165
David Benjaminc9775322018-04-13 16:39:12 -04004166using TicketAEADMethodParam =
4167 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4168
Adam Langley4c341d02017-03-08 19:33:21 -08004169class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004170 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004171
4172TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004173 bssl::UniquePtr<SSL_CTX> server_ctx =
4174 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004175 ASSERT_TRUE(server_ctx);
4176 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4177 ASSERT_TRUE(client_ctx);
4178
4179 const uint16_t version = testing::get<0>(GetParam());
4180 const unsigned retry_count = testing::get<1>(GetParam());
4181 const ssl_test_ticket_aead_failure_mode failure_mode =
4182 testing::get<2>(GetParam());
4183
Adam Langley4c341d02017-03-08 19:33:21 -08004184 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4185 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4186 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4187 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4188
4189 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4190 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4191 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4192 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004193 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004194
4195 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4196
4197 bssl::UniquePtr<SSL> client, server;
4198 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4199 server_ctx.get(), retry_count,
4200 failure_mode, nullptr);
4201 switch (failure_mode) {
4202 case ssl_test_ticket_aead_ok:
4203 case ssl_test_ticket_aead_open_hard_fail:
4204 case ssl_test_ticket_aead_open_soft_fail:
4205 ASSERT_TRUE(client);
4206 break;
4207 case ssl_test_ticket_aead_seal_fail:
4208 EXPECT_FALSE(client);
4209 return;
4210 }
4211 EXPECT_FALSE(SSL_session_reused(client.get()));
4212 EXPECT_FALSE(SSL_session_reused(server.get()));
4213
Steven Valdez777a2392019-02-21 11:30:47 -05004214 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004215 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004216 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4217 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004218 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004219 switch (failure_mode) {
4220 case ssl_test_ticket_aead_ok:
4221 ASSERT_TRUE(client);
4222 EXPECT_TRUE(SSL_session_reused(client.get()));
4223 EXPECT_TRUE(SSL_session_reused(server.get()));
4224 break;
4225 case ssl_test_ticket_aead_seal_fail:
4226 abort();
4227 break;
4228 case ssl_test_ticket_aead_open_hard_fail:
4229 EXPECT_FALSE(client);
4230 break;
4231 case ssl_test_ticket_aead_open_soft_fail:
4232 ASSERT_TRUE(client);
4233 EXPECT_FALSE(SSL_session_reused(client.get()));
4234 EXPECT_FALSE(SSL_session_reused(server.get()));
4235 }
4236}
4237
David Benjaminc9775322018-04-13 16:39:12 -04004238std::string TicketAEADMethodParamToString(
4239 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4240 std::string ret = GetVersionName(std::get<0>(params.param));
4241 // GTest only allows alphanumeric characters and '_' in the parameter
4242 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4243 for (auto it = ret.begin(); it != ret.end();) {
4244 if (*it == '.' || *it == 'v') {
4245 it = ret.erase(it);
4246 } else {
4247 ++it;
4248 }
4249 }
4250 char retry_count[256];
4251 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
4252 ret += "_";
4253 ret += retry_count;
4254 ret += "Retries_";
4255 switch (std::get<2>(params.param)) {
4256 case ssl_test_ticket_aead_ok:
4257 ret += "OK";
4258 break;
4259 case ssl_test_ticket_aead_seal_fail:
4260 ret += "SealFail";
4261 break;
4262 case ssl_test_ticket_aead_open_soft_fail:
4263 ret += "OpenSoftFail";
4264 break;
4265 case ssl_test_ticket_aead_open_hard_fail:
4266 ret += "OpenHardFail";
4267 break;
4268 }
4269 return ret;
4270}
4271
David Benjaminbe7006a2019-04-09 18:05:02 -05004272INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004273 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004274 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4275 testing::Values(0, 1, 2),
4276 testing::Values(ssl_test_ticket_aead_ok,
4277 ssl_test_ticket_aead_seal_fail,
4278 ssl_test_ticket_aead_open_soft_fail,
4279 ssl_test_ticket_aead_open_hard_fail)),
4280 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004281
David Benjaminca743582017-06-15 17:51:35 -04004282TEST(SSLTest, SelectNextProto) {
4283 uint8_t *result;
4284 uint8_t result_len;
4285
4286 // If there is an overlap, it should be returned.
4287 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4288 SSL_select_next_proto(&result, &result_len,
4289 (const uint8_t *)"\1a\2bb\3ccc", 9,
4290 (const uint8_t *)"\1x\1y\1a\1z", 8));
4291 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4292
4293 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4294 SSL_select_next_proto(&result, &result_len,
4295 (const uint8_t *)"\1a\2bb\3ccc", 9,
4296 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4297 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4298
4299 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4300 SSL_select_next_proto(&result, &result_len,
4301 (const uint8_t *)"\1a\2bb\3ccc", 9,
4302 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4303 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4304
4305 // Peer preference order takes precedence over local.
4306 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4307 SSL_select_next_proto(&result, &result_len,
4308 (const uint8_t *)"\1a\2bb\3ccc", 9,
4309 (const uint8_t *)"\3ccc\2bb\1a", 9));
4310 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4311
4312 // If there is no overlap, return the first local protocol.
4313 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4314 SSL_select_next_proto(&result, &result_len,
4315 (const uint8_t *)"\1a\2bb\3ccc", 9,
4316 (const uint8_t *)"\1x\2yy\3zzz", 9));
4317 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4318
4319 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4320 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4321 (const uint8_t *)"\1x\2yy\3zzz", 9));
4322 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4323}
4324
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004325TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004326 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004327 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004328 ASSERT_TRUE(client_ctx);
4329 ASSERT_TRUE(server_ctx);
4330
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004331 bssl::UniquePtr<SSL> client, server;
4332 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004333 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004334
4335 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4336 std::vector<uint8_t> prefix(
4337 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004338 body(record.size()),
4339 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004340 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4341 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004342 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004343
4344 std::vector<uint8_t> sealed;
4345 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4346 sealed.insert(sealed.end(), body.begin(), body.end());
4347 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4348 std::vector<uint8_t> sealed_copy = sealed;
4349
4350 bssl::Span<uint8_t> plaintext;
4351 size_t record_len;
4352 uint8_t alert = 255;
4353 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4354 bssl::MakeSpan(sealed)),
4355 bssl::OpenRecordResult::kOK);
4356 EXPECT_EQ(record_len, sealed.size());
4357 EXPECT_EQ(plaintext, record);
4358 EXPECT_EQ(255, alert);
4359}
4360
4361TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004362 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004363 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004364 ASSERT_TRUE(client_ctx);
4365 ASSERT_TRUE(server_ctx);
4366
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004367 bssl::UniquePtr<SSL> client, server;
4368 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004369 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004370
4371 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4372 std::vector<uint8_t> record = plaintext;
4373 std::vector<uint8_t> prefix(
4374 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004375 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004376 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4377 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004378 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004379 record.insert(record.begin(), prefix.begin(), prefix.end());
4380 record.insert(record.end(), suffix.begin(), suffix.end());
4381
4382 bssl::Span<uint8_t> result;
4383 size_t record_len;
4384 uint8_t alert;
4385 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4386 bssl::MakeSpan(record)),
4387 bssl::OpenRecordResult::kOK);
4388 EXPECT_EQ(record_len, record.size());
4389 EXPECT_EQ(plaintext, result);
4390}
4391
4392TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004393 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004394 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004395 ASSERT_TRUE(client_ctx);
4396 ASSERT_TRUE(server_ctx);
4397
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004398 bssl::UniquePtr<SSL> client, server;
4399 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004400 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004401
4402 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4403 std::vector<uint8_t> record = plaintext;
4404 std::vector<uint8_t> prefix(
4405 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004406 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004407 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4408 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004409 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004410 record.insert(record.begin(), prefix.begin(), prefix.end());
4411 record.insert(record.end(), suffix.begin(), suffix.end());
4412 record.insert(record.end(), {5, 4, 3, 2, 1});
4413
4414 bssl::Span<uint8_t> result;
4415 size_t record_len;
4416 uint8_t alert;
4417 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4418 bssl::MakeSpan(record)),
4419 bssl::OpenRecordResult::kOK);
4420 EXPECT_EQ(record_len, record.size() - 5);
4421 EXPECT_EQ(plaintext, result);
4422}
4423
4424TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004425 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004426 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004427 ASSERT_TRUE(client_ctx);
4428 ASSERT_TRUE(server_ctx);
4429
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004430 bssl::UniquePtr<SSL> client, server;
4431 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004432 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004433
4434 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4435 std::vector<uint8_t> prefix(
4436 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004437 body(record.size()),
4438 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004439
4440 auto expect_err = []() {
4441 int err = ERR_get_error();
4442 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4443 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4444 ERR_clear_error();
4445 };
4446 EXPECT_FALSE(bssl::SealRecord(
4447 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004448 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004449 expect_err();
4450 EXPECT_FALSE(bssl::SealRecord(
4451 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004452 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004453 expect_err();
4454
4455 EXPECT_FALSE(
4456 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4457 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004458 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004459 expect_err();
4460 EXPECT_FALSE(
4461 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4462 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004463 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004464 expect_err();
4465
4466 EXPECT_FALSE(bssl::SealRecord(
4467 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004468 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004469 expect_err();
4470 EXPECT_FALSE(bssl::SealRecord(
4471 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004472 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004473 expect_err();
4474}
4475
David Benjamin617b8182017-08-29 15:33:10 -04004476// The client should gracefully handle no suitable ciphers being enabled.
4477TEST(SSLTest, NoCiphersAvailable) {
4478 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4479 ASSERT_TRUE(ctx);
4480
4481 // Configure |client_ctx| with a cipher list that does not intersect with its
4482 // version configuration.
4483 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4484 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4485 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4486
4487 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4488 ASSERT_TRUE(ssl);
4489 SSL_set_connect_state(ssl.get());
4490
4491 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4492 ASSERT_TRUE(rbio);
4493 ASSERT_TRUE(wbio);
4494 SSL_set0_rbio(ssl.get(), rbio.release());
4495 SSL_set0_wbio(ssl.get(), wbio.release());
4496
4497 int ret = SSL_do_handshake(ssl.get());
4498 EXPECT_EQ(-1, ret);
4499 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4500 uint32_t err = ERR_get_error();
4501 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4502 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4503}
4504
David Benjamina4bafd32017-10-03 15:06:29 -04004505TEST_P(SSLVersionTest, SessionVersion) {
4506 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4507 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4508
4509 bssl::UniquePtr<SSL_SESSION> session =
4510 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4511 ASSERT_TRUE(session);
4512 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4513
4514 // Sessions in TLS 1.3 and later should be single-use.
4515 EXPECT_EQ(version() == TLS1_3_VERSION,
4516 !!SSL_SESSION_should_be_single_use(session.get()));
4517
4518 // Making fake sessions for testing works.
4519 session.reset(SSL_SESSION_new(client_ctx_.get()));
4520 ASSERT_TRUE(session);
4521 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4522 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4523}
4524
David Benjaminfdb7a352017-10-12 17:34:18 -04004525TEST_P(SSLVersionTest, SSLPending) {
4526 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4527 ASSERT_TRUE(ssl);
4528 EXPECT_EQ(0, SSL_pending(ssl.get()));
4529
4530 ASSERT_TRUE(Connect());
4531 EXPECT_EQ(0, SSL_pending(client_.get()));
4532
4533 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4534 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4535 EXPECT_EQ(0, SSL_pending(client_.get()));
4536
4537 char buf[10];
4538 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4539 EXPECT_EQ(5, SSL_pending(client_.get()));
4540
4541 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4542 EXPECT_EQ(4, SSL_pending(client_.get()));
4543
4544 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4545 EXPECT_EQ(0, SSL_pending(client_.get()));
4546
4547 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4548 EXPECT_EQ(3, SSL_pending(client_.get()));
4549}
4550
David Benjamina031b612017-10-11 20:48:25 -04004551// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4552TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004553 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004554 ASSERT_TRUE(ctx);
4555 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4556 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4557
David Benjamina031b612017-10-11 20:48:25 -04004558 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4559
4560 bssl::UniquePtr<SSL> client, server;
4561 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4562
4563 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4564 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4565 return 0;
4566 });
4567
4568 // Send close_notify.
4569 EXPECT_EQ(0, SSL_shutdown(server.get()));
4570 EXPECT_EQ(0, SSL_shutdown(client.get()));
4571
4572 // Receive close_notify.
4573 EXPECT_EQ(1, SSL_shutdown(server.get()));
4574 EXPECT_EQ(1, SSL_shutdown(client.get()));
4575}
4576
David Benjamin6cc352e2017-11-02 17:21:39 -04004577TEST(SSLTest, SignatureAlgorithmProperties) {
4578 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4579 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4580 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4581
4582 EXPECT_EQ(EVP_PKEY_RSA,
4583 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4584 EXPECT_EQ(EVP_md5_sha1(),
4585 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4586 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4587
4588 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4589 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4590 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4591 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4592 EXPECT_FALSE(
4593 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4594
4595 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004596 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004597 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004598 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4599 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004600}
4601
Adam Langley85967952018-07-03 08:04:58 -07004602static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4603 size_t in_len) {
4604 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004605 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004606 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004607 }
4608 }
4609
4610 SSL_set_app_data(ssl, XORCompressFunc);
4611
Adam Langley85967952018-07-03 08:04:58 -07004612 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004613}
4614
Adam Langley85967952018-07-03 08:04:58 -07004615static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4616 size_t uncompressed_len, const uint8_t *in,
4617 size_t in_len) {
4618 if (in_len != uncompressed_len) {
4619 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004620 }
4621
4622 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004623 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4624 if (*out == nullptr) {
4625 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004626 }
4627
Adam Langley85967952018-07-03 08:04:58 -07004628 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004629 data[i] = in[i] ^ 0x55;
4630 }
4631
4632 SSL_set_app_data(ssl, XORDecompressFunc);
4633
Adam Langley85967952018-07-03 08:04:58 -07004634 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004635}
4636
4637TEST(SSLTest, CertCompression) {
4638 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004639 bssl::UniquePtr<SSL_CTX> server_ctx(
4640 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004641 ASSERT_TRUE(client_ctx);
4642 ASSERT_TRUE(server_ctx);
4643
Adam Langley0080d832018-06-07 16:39:49 -07004644 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4645 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4646 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4647 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4648 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4649 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4650
4651 bssl::UniquePtr<SSL> client, server;
4652 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4653 server_ctx.get()));
4654
4655 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4656 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4657}
4658
Adam Langleyddb57cf2018-01-26 09:17:53 -08004659void MoveBIOs(SSL *dest, SSL *src) {
4660 BIO *rbio = SSL_get_rbio(src);
4661 BIO_up_ref(rbio);
4662 SSL_set0_rbio(dest, rbio);
4663
4664 BIO *wbio = SSL_get_wbio(src);
4665 BIO_up_ref(wbio);
4666 SSL_set0_wbio(dest, wbio);
4667
4668 SSL_set0_rbio(src, nullptr);
4669 SSL_set0_wbio(src, nullptr);
4670}
4671
4672TEST(SSLTest, Handoff) {
4673 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4674 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004675 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4676 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004677 ASSERT_TRUE(client_ctx);
4678 ASSERT_TRUE(server_ctx);
4679 ASSERT_TRUE(handshaker_ctx);
4680
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004681 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4682 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004683 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004684 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004685 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004686 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004687
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004688 for (bool early_data : {false, true}) {
4689 SCOPED_TRACE(early_data);
4690 for (bool is_resume : {false, true}) {
4691 SCOPED_TRACE(is_resume);
4692 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004693 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4694 server_ctx.get()));
4695 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004696 if (is_resume) {
4697 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004698 SSL_set_session(client.get(), g_last_session.get());
4699 if (early_data) {
4700 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4701 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004702 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004703
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004704
4705 int client_ret = SSL_do_handshake(client.get());
4706 int client_err = SSL_get_error(client.get(), client_ret);
4707
4708 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004709 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004710 ASSERT_EQ(client_err, 0);
4711 EXPECT_TRUE(SSL_in_early_data(client.get()));
4712 // Attempt to write early data.
4713 byte_written = 43;
4714 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4715 } else {
4716 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4717 }
4718
4719 int server_ret = SSL_do_handshake(server.get());
4720 int server_err = SSL_get_error(server.get(), server_ret);
4721 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4722
4723 ScopedCBB cbb;
4724 Array<uint8_t> handoff;
4725 SSL_CLIENT_HELLO hello;
4726 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4727 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4728 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4729
4730 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4731 // Note split handshakes determines 0-RTT support, for both the current
4732 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4733 // no need to call |SSL_set_early_data_enabled| on |server|.
4734 SSL_set_early_data_enabled(handshaker.get(), 1);
4735 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4736
4737 MoveBIOs(handshaker.get(), server.get());
4738
4739 int handshake_ret = SSL_do_handshake(handshaker.get());
4740 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4741 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4742
4743 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004744 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004745 handshake_ret = SSL_do_handshake(handshaker.get());
4746 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4747 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4748
4749 ScopedCBB cbb_handback;
4750 Array<uint8_t> handback;
4751 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4752 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4753 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4754
4755 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4756 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4757
4758 MoveBIOs(server2.get(), handshaker.get());
4759 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4760 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4761
David Benjamin9b2cdb72021-04-01 23:21:53 -04004762 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004763 // In this case, one byte of early data has already been written above.
4764 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4765 } else {
4766 byte_written = 42;
4767 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4768 }
4769 uint8_t byte;
4770 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4771 EXPECT_EQ(byte_written, byte);
4772
4773 byte = 44;
4774 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4775 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4776 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004777 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004778 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004779}
4780
4781TEST(SSLTest, HandoffDeclined) {
4782 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004783 bssl::UniquePtr<SSL_CTX> server_ctx(
4784 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004785 ASSERT_TRUE(client_ctx);
4786 ASSERT_TRUE(server_ctx);
4787
4788 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4789 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4790
Adam Langleyddb57cf2018-01-26 09:17:53 -08004791 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004792 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4793 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004794
4795 int client_ret = SSL_do_handshake(client.get());
4796 int client_err = SSL_get_error(client.get(), client_ret);
4797 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4798
4799 int server_ret = SSL_do_handshake(server.get());
4800 int server_err = SSL_get_error(server.get(), server_ret);
4801 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4802
4803 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004804 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004805 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004806 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004807
4808 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4809
4810 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4811
4812 uint8_t byte = 42;
4813 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4814 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4815 EXPECT_EQ(42, byte);
4816
4817 byte = 43;
4818 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4819 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4820 EXPECT_EQ(43, byte);
4821}
4822
Adam Langley826ce152018-08-03 10:31:21 -07004823static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4824 std::string ret = "{";
4825
4826 for (uint16_t v : sigalgs) {
4827 if (ret.size() > 1) {
4828 ret += ", ";
4829 }
4830
4831 char buf[8];
4832 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4833 buf[sizeof(buf)-1] = 0;
4834 ret += std::string(buf);
4835 }
4836
4837 ret += "}";
4838 return ret;
4839}
4840
4841void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4842 Span<const uint16_t> actual) {
4843 bool matches = false;
4844 if (expected.size() == actual.size()) {
4845 matches = true;
4846
4847 for (size_t i = 0; i < expected.size(); i++) {
4848 if (expected[i] != actual[i]) {
4849 matches = false;
4850 break;
4851 }
4852 }
4853 }
4854
4855 if (!matches) {
4856 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4857 << " got: " << SigAlgsToString(actual);
4858 }
4859}
4860
4861TEST(SSLTest, SigAlgs) {
4862 static const struct {
4863 std::vector<int> input;
4864 bool ok;
4865 std::vector<uint16_t> expected;
4866 } kTests[] = {
4867 {{}, true, {}},
4868 {{1}, false, {}},
4869 {{1, 2, 3}, false, {}},
4870 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4871 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4872
4873 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4874 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4875 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4876 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4877 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4878 true,
4879 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4880 };
4881
4882 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4883
4884 unsigned n = 1;
4885 for (const auto &test : kTests) {
4886 SCOPED_TRACE(n++);
4887
4888 const bool ok =
4889 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4890 EXPECT_EQ(ok, test.ok);
4891
4892 if (!ok) {
4893 ERR_clear_error();
4894 }
4895
4896 if (!test.ok) {
4897 continue;
4898 }
4899
4900 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4901 }
4902}
4903
4904TEST(SSLTest, SigAlgsList) {
4905 static const struct {
4906 const char *input;
4907 bool ok;
4908 std::vector<uint16_t> expected;
4909 } kTests[] = {
4910 {"", false, {}},
4911 {":", false, {}},
4912 {"+", false, {}},
4913 {"RSA", false, {}},
4914 {"RSA+", false, {}},
4915 {"RSA+SHA256:", false, {}},
4916 {":RSA+SHA256:", false, {}},
4917 {":RSA+SHA256+:", false, {}},
4918 {"!", false, {}},
4919 {"\x01", false, {}},
4920 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4921 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4922
4923 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4924 {"RSA+SHA256:ed25519",
4925 true,
4926 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4927 {"ECDSA+SHA256:RSA+SHA512",
4928 true,
4929 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4930 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4931 true,
4932 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4933 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4934 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4935 };
4936
4937 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4938
4939 unsigned n = 1;
4940 for (const auto &test : kTests) {
4941 SCOPED_TRACE(n++);
4942
4943 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4944 EXPECT_EQ(ok, test.ok);
4945
4946 if (!ok) {
4947 if (test.ok) {
4948 ERR_print_errors_fp(stderr);
4949 }
4950 ERR_clear_error();
4951 }
4952
4953 if (!test.ok) {
4954 continue;
4955 }
4956
4957 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4958 }
4959}
4960
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004961TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4962 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4963 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4964
4965 // handoff is a handoff message that has been artificially modified to pretend
4966 // that only cipher 0x0A is supported. When it is applied to |server|, all
4967 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004968 //
4969 // To make a new one of these, try sticking this in the |Handoff| test above:
4970 //
4971 // hexdump(stderr, "", handoff.data(), handoff.size());
4972 // sed -e 's/\(..\)/0x\1, /g'
4973 //
4974 // and modify serialize_features() to emit only cipher 0x0A.
4975
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004976 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004977 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4978 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4979 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4980 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4981 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004982 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4983 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004984 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4985 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4986 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4987 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4988 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4989 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4990 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004991 };
4992
4993 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4994 ASSERT_TRUE(
4995 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4996 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4997}
4998
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004999TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5000 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5001 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5002
5003 // handoff is a handoff message that has been artificially modified to pretend
5004 // that only one curve is supported. When it is applied to |server|, all
5005 // curves but that one should be removed.
5006 //
5007 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5008 // these.
5009 uint8_t handoff[] = {
5010 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5011 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5012 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5013 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5014 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5015 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5016 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5017 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5018 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5019 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5020 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5021 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5022 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5023 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5024 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5025 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5026 0x02, 0x00, 0x17,
5027 };
5028
5029 // The zero length means that the default list of groups is used.
5030 EXPECT_EQ(0u, server->config->supported_group_list.size());
5031 ASSERT_TRUE(
5032 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5033 EXPECT_EQ(1u, server->config->supported_group_list.size());
5034}
5035
Adam Langleyba9ad662018-12-17 13:59:38 -08005036TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5037 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5038 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005039 bssl::UniquePtr<SSL_CTX> server_ctx(
5040 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005041 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5042 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005043
5044 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5045 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5046 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5047
5048 bssl::UniquePtr<SSL> client, server;
5049 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5050 server_ctx.get()));
5051
5052 BIO *client_wbio = SSL_get_wbio(client.get());
5053 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5054 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5055 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5056 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5057 EXPECT_NE(0u, BIO_wpending(client_wbio));
5058}
5059
David Benjamin5869eb32018-07-17 00:59:45 -04005060TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5061 // Configure the server to request client certificates.
5062 SSL_CTX_set_custom_verify(
5063 server_ctx_.get(), SSL_VERIFY_PEER,
5064 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5065
5066 // Configure the client to reject the server certificate.
5067 SSL_CTX_set_custom_verify(
5068 client_ctx_.get(), SSL_VERIFY_PEER,
5069 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5070
5071 // cert_cb should not be called. Verification should fail first.
5072 SSL_CTX_set_cert_cb(client_ctx_.get(),
5073 [](SSL *ssl, void *arg) {
5074 ADD_FAILURE() << "cert_cb unexpectedly called";
5075 return 0;
5076 },
5077 nullptr);
5078
5079 bssl::UniquePtr<SSL> client, server;
5080 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5081 server_ctx_.get()));
5082}
5083
David Benjamin492c9aa2018-08-31 16:35:22 -05005084// Test that ticket-based sessions on the client get fake session IDs.
5085TEST_P(SSLVersionTest, FakeIDsForTickets) {
5086 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5087 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5088
5089 bssl::UniquePtr<SSL_SESSION> session =
5090 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5091 ASSERT_TRUE(session);
5092
5093 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5094 unsigned session_id_length;
5095 SSL_SESSION_get_id(session.get(), &session_id_length);
5096 EXPECT_NE(session_id_length, 0u);
5097}
5098
David Benjamin6c04bd12018-07-19 18:13:09 -04005099// These tests test multi-threaded behavior. They are intended to run with
5100// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005101#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005102TEST_P(SSLVersionTest, SessionCacheThreads) {
5103 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5104 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5105 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5106
5107 if (version() == TLS1_3_VERSION) {
5108 // Our TLS 1.3 implementation does not support stateful resumption.
5109 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5110 return;
5111 }
5112
5113 // Establish two client sessions to test with.
5114 bssl::UniquePtr<SSL_SESSION> session1 =
5115 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5116 ASSERT_TRUE(session1);
5117 bssl::UniquePtr<SSL_SESSION> session2 =
5118 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5119 ASSERT_TRUE(session2);
5120
5121 auto connect_with_session = [&](SSL_SESSION *session) {
5122 ClientConfig config;
5123 config.session = session;
5124 UniquePtr<SSL> client, server;
5125 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5126 server_ctx_.get(), config));
5127 };
5128
5129 // Resume sessions in parallel with establishing new ones.
5130 {
5131 std::vector<std::thread> threads;
5132 threads.emplace_back([&] { connect_with_session(nullptr); });
5133 threads.emplace_back([&] { connect_with_session(nullptr); });
5134 threads.emplace_back([&] { connect_with_session(session1.get()); });
5135 threads.emplace_back([&] { connect_with_session(session1.get()); });
5136 threads.emplace_back([&] { connect_with_session(session2.get()); });
5137 threads.emplace_back([&] { connect_with_session(session2.get()); });
5138 for (auto &thread : threads) {
5139 thread.join();
5140 }
5141 }
5142
5143 // Hit the maximum session cache size across multiple threads
5144 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5145 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5146 {
5147 std::vector<std::thread> threads;
5148 for (int i = 0; i < 4; i++) {
5149 threads.emplace_back([&]() {
5150 connect_with_session(nullptr);
5151 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5152 });
5153 }
5154 for (auto &thread : threads) {
5155 thread.join();
5156 }
5157 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5158 }
5159}
5160
5161TEST_P(SSLVersionTest, SessionTicketThreads) {
5162 for (bool renew_ticket : {false, true}) {
5163 SCOPED_TRACE(renew_ticket);
5164 ResetContexts();
5165 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5166 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5167 if (renew_ticket) {
5168 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5169 }
5170
5171 // Establish two client sessions to test with.
5172 bssl::UniquePtr<SSL_SESSION> session1 =
5173 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5174 ASSERT_TRUE(session1);
5175 bssl::UniquePtr<SSL_SESSION> session2 =
5176 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5177 ASSERT_TRUE(session2);
5178
5179 auto connect_with_session = [&](SSL_SESSION *session) {
5180 ClientConfig config;
5181 config.session = session;
5182 UniquePtr<SSL> client, server;
5183 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5184 server_ctx_.get(), config));
5185 };
5186
5187 // Resume sessions in parallel with establishing new ones.
5188 {
5189 std::vector<std::thread> threads;
5190 threads.emplace_back([&] { connect_with_session(nullptr); });
5191 threads.emplace_back([&] { connect_with_session(nullptr); });
5192 threads.emplace_back([&] { connect_with_session(session1.get()); });
5193 threads.emplace_back([&] { connect_with_session(session1.get()); });
5194 threads.emplace_back([&] { connect_with_session(session2.get()); });
5195 threads.emplace_back([&] { connect_with_session(session2.get()); });
5196 for (auto &thread : threads) {
5197 thread.join();
5198 }
5199 }
5200 }
5201}
5202
5203// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5204TEST(SSLTest, GetCertificateThreads) {
5205 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5206 ASSERT_TRUE(ctx);
5207 bssl::UniquePtr<X509> cert = GetTestCertificate();
5208 ASSERT_TRUE(cert);
5209 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5210
5211 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5212 // threads concurrently. It originally was an immutable operation. Now we
5213 // implement it with a thread-safe cache, so it is worth testing.
5214 X509 *cert2_thread;
5215 std::thread thread(
5216 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5217 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5218 thread.join();
5219
5220 EXPECT_EQ(cert2, cert2_thread);
5221 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5222}
David Benjamin4cce9552018-12-13 12:20:54 -06005223
5224// Functions which access properties on the negotiated session are thread-safe
5225// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5226// performing stateful resumption will share an underlying SSL_SESSION object,
5227// potentially across threads.
5228TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5229 if (version() == TLS1_3_VERSION) {
5230 // Our TLS 1.3 implementation does not support stateful resumption.
5231 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5232 return;
5233 }
5234
5235 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5236 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5237 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5238
5239 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5240 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5241
5242 // Configure mutual authentication, so we have more session state.
5243 SSL_CTX_set_custom_verify(
5244 client_ctx_.get(), SSL_VERIFY_PEER,
5245 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5246 SSL_CTX_set_custom_verify(
5247 server_ctx_.get(), SSL_VERIFY_PEER,
5248 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5249
5250 // Establish a client session to test with.
5251 bssl::UniquePtr<SSL_SESSION> session =
5252 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5253 ASSERT_TRUE(session);
5254
5255 // Resume with it twice.
5256 UniquePtr<SSL> ssls[4];
5257 ClientConfig config;
5258 config.session = session.get();
5259 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5260 server_ctx_.get(), config));
5261 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5262 server_ctx_.get(), config));
5263
5264 // Read properties in parallel.
5265 auto read_properties = [](const SSL *ssl) {
5266 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5267 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5268 EXPECT_TRUE(peer);
5269 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5270 EXPECT_TRUE(SSL_get_curve_id(ssl));
5271 };
5272
5273 std::vector<std::thread> threads;
5274 for (const auto &ssl_ptr : ssls) {
5275 const SSL *ssl = ssl_ptr.get();
5276 threads.emplace_back([=] { read_properties(ssl); });
5277 }
5278 for (auto &thread : threads) {
5279 thread.join();
5280 }
5281}
David Benjamina486c6c2019-03-28 18:32:38 -05005282#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005283
Steven Valdezc8e0f902018-07-14 11:23:01 -04005284constexpr size_t kNumQUICLevels = 4;
5285static_assert(ssl_encryption_initial < kNumQUICLevels,
5286 "kNumQUICLevels is wrong");
5287static_assert(ssl_encryption_early_data < kNumQUICLevels,
5288 "kNumQUICLevels is wrong");
5289static_assert(ssl_encryption_handshake < kNumQUICLevels,
5290 "kNumQUICLevels is wrong");
5291static_assert(ssl_encryption_application < kNumQUICLevels,
5292 "kNumQUICLevels is wrong");
5293
David Benjamin1e859052020-02-09 16:04:58 -05005294const char *LevelToString(ssl_encryption_level_t level) {
5295 switch (level) {
5296 case ssl_encryption_initial:
5297 return "initial";
5298 case ssl_encryption_early_data:
5299 return "early data";
5300 case ssl_encryption_handshake:
5301 return "handshake";
5302 case ssl_encryption_application:
5303 return "application";
5304 }
5305 return "<unknown>";
5306}
5307
Steven Valdezc8e0f902018-07-14 11:23:01 -04005308class MockQUICTransport {
5309 public:
David Benjamind6343572019-08-15 17:29:02 -04005310 enum class Role { kClient, kServer };
5311
5312 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005313 // The caller is expected to configure initial secrets.
5314 levels_[ssl_encryption_initial].write_secret = {1};
5315 levels_[ssl_encryption_initial].read_secret = {1};
5316 }
5317
5318 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5319
5320 bool has_alert() const { return has_alert_; }
5321 ssl_encryption_level_t alert_level() const { return alert_level_; }
5322 uint8_t alert() const { return alert_; }
5323
5324 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5325 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005326 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5327 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005328 }
5329
David Benjamin1e859052020-02-09 16:04:58 -05005330 bool HasReadSecret(ssl_encryption_level_t level) const {
5331 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005332 }
5333
David Benjamin1e859052020-02-09 16:04:58 -05005334 bool HasWriteSecret(ssl_encryption_level_t level) const {
5335 return !levels_[level].write_secret.empty();
5336 }
5337
David Benjamin5298ef92020-03-13 12:17:30 -04005338 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5339
David Benjamin1e859052020-02-09 16:04:58 -05005340 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5341 Span<const uint8_t> secret) {
5342 if (HasReadSecret(level)) {
5343 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5344 return false;
5345 }
5346
5347 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5348 ADD_FAILURE() << "Unexpected early data read secret";
5349 return false;
5350 }
5351
5352 ssl_encryption_level_t ack_level =
5353 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5354 if (!HasWriteSecret(ack_level)) {
5355 ADD_FAILURE() << LevelToString(level)
5356 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005357 return false;
5358 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005359
5360 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005361 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005362 return false;
5363 }
5364
David Benjamin1e859052020-02-09 16:04:58 -05005365 if (level != ssl_encryption_early_data &&
5366 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5367 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005368 return false;
5369 }
David Benjamind6343572019-08-15 17:29:02 -04005370
David Benjamin1e859052020-02-09 16:04:58 -05005371 levels_[level].read_secret.assign(secret.begin(), secret.end());
5372 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5373 return true;
5374 }
5375
5376 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5377 Span<const uint8_t> secret) {
5378 if (HasWriteSecret(level)) {
5379 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005380 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005381 }
David Benjamind6343572019-08-15 17:29:02 -04005382
David Benjamin1e859052020-02-09 16:04:58 -05005383 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5384 ADD_FAILURE() << "Unexpected early data write secret";
5385 return false;
5386 }
5387
5388 if (cipher == nullptr) {
5389 ADD_FAILURE() << "Unexpected null cipher";
5390 return false;
5391 }
5392
5393 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005394 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005395 return true;
5396 }
5397
5398 bool WriteHandshakeData(ssl_encryption_level_t level,
5399 Span<const uint8_t> data) {
5400 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005401 ADD_FAILURE() << LevelToString(level)
5402 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005403 return false;
5404 }
David Benjamin5298ef92020-03-13 12:17:30 -04005405
5406 // Although the levels are conceptually separate, BoringSSL finishes writing
5407 // data from a previous level before installing keys for the next level.
5408 if (!allow_out_of_order_writes_) {
5409 switch (level) {
5410 case ssl_encryption_early_data:
5411 ADD_FAILURE() << "unexpected handshake data at early data level";
5412 return false;
5413 case ssl_encryption_initial:
5414 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5415 ADD_FAILURE()
5416 << LevelToString(level)
5417 << " handshake data written after handshake keys installed";
5418 return false;
5419 }
5420 OPENSSL_FALLTHROUGH;
5421 case ssl_encryption_handshake:
5422 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5423 ADD_FAILURE()
5424 << LevelToString(level)
5425 << " handshake data written after application keys installed";
5426 return false;
5427 }
5428 OPENSSL_FALLTHROUGH;
5429 case ssl_encryption_application:
5430 break;
5431 }
5432 }
5433
Steven Valdezc8e0f902018-07-14 11:23:01 -04005434 levels_[level].write_data.insert(levels_[level].write_data.end(),
5435 data.begin(), data.end());
5436 return true;
5437 }
5438
5439 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5440 if (has_alert_) {
5441 ADD_FAILURE() << "duplicate alert sent";
5442 return false;
5443 }
5444
5445 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005446 ADD_FAILURE() << LevelToString(level)
5447 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005448 return false;
5449 }
5450
5451 has_alert_ = true;
5452 alert_level_ = level;
5453 alert_ = alert_value;
5454 return true;
5455 }
5456
5457 bool ReadHandshakeData(std::vector<uint8_t> *out,
5458 ssl_encryption_level_t level,
5459 size_t num = std::numeric_limits<size_t>::max()) {
5460 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005461 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005462 return false;
5463 }
5464 // The peer may not have configured any keys yet.
5465 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005466 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005467 return true;
5468 }
5469 // Check the peer computed the same key.
5470 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005471 ADD_FAILURE() << "peer write key does not match read key in level "
5472 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005473 return false;
5474 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005475 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005476 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005477 return false;
5478 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005479 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5480 num = std::min(num, peer_data->size());
5481 out->assign(peer_data->begin(), peer_data->begin() + num);
5482 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5483 return true;
5484 }
5485
5486 private:
David Benjamind6343572019-08-15 17:29:02 -04005487 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005488 MockQUICTransport *peer_ = nullptr;
5489
David Benjamin5298ef92020-03-13 12:17:30 -04005490 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005491 bool has_alert_ = false;
5492 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5493 uint8_t alert_ = 0;
5494
5495 struct Level {
5496 std::vector<uint8_t> write_data;
5497 std::vector<uint8_t> write_secret;
5498 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005499 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005500 };
5501 Level levels_[kNumQUICLevels];
5502};
5503
5504class MockQUICTransportPair {
5505 public:
David Benjamind6343572019-08-15 17:29:02 -04005506 MockQUICTransportPair()
5507 : client_(MockQUICTransport::Role::kClient),
5508 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005509 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005510 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005511 }
5512
5513 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005514 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005515 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005516 }
5517
5518 MockQUICTransport *client() { return &client_; }
5519 MockQUICTransport *server() { return &server_; }
5520
5521 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005522 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5523 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5524 return client_.PeerSecretsMatch(level) &&
5525 client_.HasWriteSecret(level) &&
5526 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005527 }
5528
5529 private:
5530 MockQUICTransport client_;
5531 MockQUICTransport server_;
5532};
5533
5534class QUICMethodTest : public testing::Test {
5535 protected:
5536 void SetUp() override {
5537 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005538 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005539 ASSERT_TRUE(client_ctx_);
5540 ASSERT_TRUE(server_ctx_);
5541
Steven Valdezc8e0f902018-07-14 11:23:01 -04005542 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5543 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5544 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5545 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005546
5547 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5548 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5549 sizeof(kALPNProtos)),
5550 0);
5551 SSL_CTX_set_alpn_select_cb(
5552 server_ctx_.get(),
5553 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5554 unsigned in_len, void *arg) -> int {
5555 return SSL_select_next_proto(
5556 const_cast<uint8_t **>(out), out_len, in, in_len,
5557 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5558 ? SSL_TLSEXT_ERR_OK
5559 : SSL_TLSEXT_ERR_NOACK;
5560 },
5561 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005562 }
5563
5564 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5565 return ex_data_.Get(ssl);
5566 }
5567
5568 static bool ProvideHandshakeData(
5569 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5570 MockQUICTransport *transport = TransportFromSSL(ssl);
5571 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5572 std::vector<uint8_t> data;
5573 return transport->ReadHandshakeData(&data, level, num) &&
5574 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5575 }
5576
David Benjamin5298ef92020-03-13 12:17:30 -04005577 void AllowOutOfOrderWrites() {
5578 allow_out_of_order_writes_ = true;
5579 }
5580
Steven Valdezc8e0f902018-07-14 11:23:01 -04005581 bool CreateClientAndServer() {
5582 client_.reset(SSL_new(client_ctx_.get()));
5583 server_.reset(SSL_new(server_ctx_.get()));
5584 if (!client_ || !server_) {
5585 return false;
5586 }
5587
5588 SSL_set_connect_state(client_.get());
5589 SSL_set_accept_state(server_.get());
5590
David Benjamind6343572019-08-15 17:29:02 -04005591 transport_.reset(new MockQUICTransportPair);
5592 ex_data_.Set(client_.get(), transport_->client());
5593 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005594 if (allow_out_of_order_writes_) {
5595 transport_->client()->AllowOutOfOrderWrites();
5596 transport_->server()->AllowOutOfOrderWrites();
5597 }
Nick Harper7c522992020-04-30 14:15:49 -07005598 static const uint8_t client_transport_params[] = {0};
5599 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5600 sizeof(client_transport_params)) ||
5601 !SSL_set_quic_transport_params(server_.get(),
5602 server_transport_params_.data(),
5603 server_transport_params_.size()) ||
5604 !SSL_set_quic_early_data_context(
5605 server_.get(), server_quic_early_data_context_.data(),
5606 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005607 return false;
5608 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005609 return true;
5610 }
5611
Nick Harper72cff812020-03-26 18:06:16 -07005612 enum class ExpectedError {
5613 kNoError,
5614 kClientError,
5615 kServerError,
5616 };
5617
David Benjamind6343572019-08-15 17:29:02 -04005618 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5619 // |server_| until each completes once. It returns true on success and false
5620 // on failure.
5621 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005622 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5623 }
5624
5625 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5626 // once. If |expect_client_error| is true, it will return true only if the
5627 // client handshake failed. Otherwise, it returns true if both handshakes
5628 // succeed and false otherwise.
5629 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005630 bool client_done = false, server_done = false;
5631 while (!client_done || !server_done) {
5632 if (!client_done) {
5633 if (!ProvideHandshakeData(client_.get())) {
5634 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5635 return false;
5636 }
5637 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005638 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005639 if (client_ret == 1) {
5640 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005641 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005642 if (expected_error == ExpectedError::kClientError) {
5643 return true;
5644 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005645 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5646 << client_err;
5647 return false;
David Benjamind6343572019-08-15 17:29:02 -04005648 }
5649 }
5650
5651 if (!server_done) {
5652 if (!ProvideHandshakeData(server_.get())) {
5653 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5654 return false;
5655 }
5656 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005657 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005658 if (server_ret == 1) {
5659 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005660 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005661 if (expected_error == ExpectedError::kServerError) {
5662 return true;
5663 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005664 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5665 << server_err;
5666 return false;
David Benjamind6343572019-08-15 17:29:02 -04005667 }
5668 }
5669 }
Nick Harper72cff812020-03-26 18:06:16 -07005670 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005671 }
5672
5673 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5674 g_last_session = nullptr;
5675 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5676 if (!CreateClientAndServer() ||
5677 !CompleteHandshakesForQUIC()) {
5678 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005679 }
5680
David Benjamind6343572019-08-15 17:29:02 -04005681 // The server sent NewSessionTicket messages in the handshake.
5682 if (!ProvideHandshakeData(client_.get()) ||
5683 !SSL_process_quic_post_handshake(client_.get())) {
5684 return nullptr;
5685 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005686
David Benjamind6343572019-08-15 17:29:02 -04005687 return std::move(g_last_session);
5688 }
5689
5690 void ExpectHandshakeSuccess() {
5691 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5692 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5693 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5694 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5695 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5696 EXPECT_FALSE(transport_->client()->has_alert());
5697 EXPECT_FALSE(transport_->server()->has_alert());
5698
5699 // SSL_do_handshake is now idempotent.
5700 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5701 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005702 }
5703
David Benjamin1e859052020-02-09 16:04:58 -05005704 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5705 // the test.
5706 SSL_QUIC_METHOD DefaultQUICMethod() {
5707 return SSL_QUIC_METHOD{
5708 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5709 FlushFlightCallback, SendAlertCallback,
5710 };
5711 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005712
David Benjamin1e859052020-02-09 16:04:58 -05005713 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5714 const SSL_CIPHER *cipher,
5715 const uint8_t *secret, size_t secret_len) {
5716 return TransportFromSSL(ssl)->SetReadSecret(
5717 level, cipher, MakeConstSpan(secret, secret_len));
5718 }
5719
5720 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5721 const SSL_CIPHER *cipher,
5722 const uint8_t *secret, size_t secret_len) {
5723 return TransportFromSSL(ssl)->SetWriteSecret(
5724 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005725 }
5726
David Benjamincc9d9352018-10-30 19:45:22 -05005727 static int AddHandshakeDataCallback(SSL *ssl,
5728 enum ssl_encryption_level_t level,
5729 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005730 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5731 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5732 MakeConstSpan(data, len));
5733 }
5734
5735 static int FlushFlightCallback(SSL *ssl) { return 1; }
5736
5737 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5738 uint8_t alert) {
5739 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5740 return TransportFromSSL(ssl)->SendAlert(level, alert);
5741 }
5742
5743 bssl::UniquePtr<SSL_CTX> client_ctx_;
5744 bssl::UniquePtr<SSL_CTX> server_ctx_;
5745
5746 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005747 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005748
5749 bssl::UniquePtr<SSL> client_;
5750 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005751
Nick Harper7c522992020-04-30 14:15:49 -07005752 std::vector<uint8_t> server_transport_params_ = {1};
5753 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5754
David Benjamin5298ef92020-03-13 12:17:30 -04005755 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005756};
5757
5758UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5759
David Benjaminfd863b62019-07-25 13:51:32 -04005760// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005761TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005762 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005763
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005764 g_last_session = nullptr;
5765
5766 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5767 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005768 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5769 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005770
Steven Valdezc8e0f902018-07-14 11:23:01 -04005771 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005772 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005773
David Benjamind6343572019-08-15 17:29:02 -04005774 ExpectHandshakeSuccess();
5775 EXPECT_FALSE(SSL_session_reused(client_.get()));
5776 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005777
5778 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005779 EXPECT_FALSE(g_last_session);
5780 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5781 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5782 EXPECT_TRUE(g_last_session);
5783
5784 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005785 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005786 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5787 SSL_set_session(client_.get(), session.get());
5788
David Benjamind6343572019-08-15 17:29:02 -04005789 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005790
David Benjamind6343572019-08-15 17:29:02 -04005791 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005792 EXPECT_TRUE(SSL_session_reused(client_.get()));
5793 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005794}
5795
David Benjaminfd863b62019-07-25 13:51:32 -04005796// Test that HelloRetryRequest in QUIC works.
5797TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05005798 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04005799
5800 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5801 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5802
5803 // BoringSSL predicts the most preferred curve, so using different preferences
5804 // will trigger HelloRetryRequest.
5805 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5806 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5807 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5808 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5809 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5810 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5811
5812 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005813 ASSERT_TRUE(CompleteHandshakesForQUIC());
5814 ExpectHandshakeSuccess();
5815}
David Benjaminfd863b62019-07-25 13:51:32 -04005816
Nick Harpere32549e2020-05-06 14:27:11 -07005817// Test that the client does not send a legacy_session_id in the ClientHello.
5818TEST_F(QUICMethodTest, NoLegacySessionId) {
5819 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5820
5821 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5822 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5823 // Check that the session ID length is 0 in an early callback.
5824 SSL_CTX_set_select_certificate_cb(
5825 server_ctx_.get(),
5826 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
5827 EXPECT_EQ(client_hello->session_id_len, 0u);
5828 return ssl_select_cert_success;
5829 });
5830
5831 ASSERT_TRUE(CreateClientAndServer());
5832 ASSERT_TRUE(CompleteHandshakesForQUIC());
5833
5834 ExpectHandshakeSuccess();
5835}
5836
David Benjamin1e859052020-02-09 16:04:58 -05005837// Test that, even in a 1-RTT handshake, the server installs keys at the right
5838// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
5839TEST_F(QUICMethodTest, HalfRTTKeys) {
5840 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5841
5842 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5843 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5844 ASSERT_TRUE(CreateClientAndServer());
5845
5846 // The client sends ClientHello.
5847 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5848 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
5849
5850 // The server reads ClientHello and sends ServerHello..Finished.
5851 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5852 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5853 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5854
5855 // At this point, the server has half-RTT write keys, but it cannot access
5856 // 1-RTT read keys until client Finished.
5857 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5858 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5859
5860 // Finish up the client and server handshakes.
5861 ASSERT_TRUE(CompleteHandshakesForQUIC());
5862
5863 // Both sides can now exchange 1-RTT data.
5864 ExpectHandshakeSuccess();
5865}
5866
David Benjamind6343572019-08-15 17:29:02 -04005867TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05005868 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005869
5870 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5871 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5872 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5873 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5874 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5875
5876 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5877 ASSERT_TRUE(session);
5878
5879 ASSERT_TRUE(CreateClientAndServer());
5880 SSL_set_session(client_.get(), session.get());
5881
5882 // The client handshake should return immediately into the early data state.
5883 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5884 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5885 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005886 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005887
5888 // The server will consume the ClientHello and also enter the early data
5889 // state.
5890 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5891 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5892 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5893 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05005894 // At this point, the server has half-RTT write keys, but it cannot access
5895 // 1-RTT read keys until client Finished.
5896 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5897 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04005898
5899 // Finish up the client and server handshakes.
5900 ASSERT_TRUE(CompleteHandshakesForQUIC());
5901
5902 // Both sides can now exchange 1-RTT data.
5903 ExpectHandshakeSuccess();
5904 EXPECT_TRUE(SSL_session_reused(client_.get()));
5905 EXPECT_TRUE(SSL_session_reused(server_.get()));
5906 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5907 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5908 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5909 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07005910
5911 // Finish handling post-handshake messages after the first 0-RTT resumption.
5912 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
5913 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
5914
5915 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
5916 // accepted again.
5917 ASSERT_TRUE(CreateClientAndServer());
5918 SSL_set_session(client_.get(), g_last_session.get());
5919
5920 // The client handshake should return immediately into the early data state.
5921 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5922 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5923 // The transport should have keys for sending 0-RTT data.
5924 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
5925
5926 // The server will consume the ClientHello and also enter the early data
5927 // state.
5928 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5929 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5930 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5931 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5932 // At this point, the server has half-RTT write keys, but it cannot access
5933 // 1-RTT read keys until client Finished.
5934 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5935 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5936
5937 // Finish up the client and server handshakes.
5938 ASSERT_TRUE(CompleteHandshakesForQUIC());
5939
5940 // Both sides can now exchange 1-RTT data.
5941 ExpectHandshakeSuccess();
5942 EXPECT_TRUE(SSL_session_reused(client_.get()));
5943 EXPECT_TRUE(SSL_session_reused(server_.get()));
5944 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5945 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5946 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5947 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5948 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
5949 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04005950}
5951
Nick Harper7c522992020-04-30 14:15:49 -07005952TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
5953 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5954
5955 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5956 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5957 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5958 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5959 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5960
5961
5962 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5963 ASSERT_TRUE(session);
5964
Nick Harper85194322020-05-20 16:59:29 -07005965 ASSERT_TRUE(CreateClientAndServer());
5966 static const uint8_t new_context[] = {4};
5967 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
5968 sizeof(new_context)));
5969 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07005970
Nick Harper85194322020-05-20 16:59:29 -07005971 // The client handshake should return immediately into the early data
5972 // state.
5973 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5974 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5975 // The transport should have keys for sending 0-RTT data.
5976 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005977
Nick Harper85194322020-05-20 16:59:29 -07005978 // The server will consume the ClientHello, but it will not accept 0-RTT.
5979 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5980 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5981 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5982 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5983 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005984
Nick Harper85194322020-05-20 16:59:29 -07005985 // The client consumes the server response and signals 0-RTT rejection.
5986 for (;;) {
5987 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5988 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5989 int err = SSL_get_error(client_.get(), -1);
5990 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5991 break;
Nick Harper7c522992020-04-30 14:15:49 -07005992 }
Nick Harper85194322020-05-20 16:59:29 -07005993 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07005994 }
Nick Harper85194322020-05-20 16:59:29 -07005995
5996 // As in TLS over TCP, 0-RTT rejection is sticky.
5997 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5998 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5999
6000 // Finish up the client and server handshakes.
6001 SSL_reset_early_data_reject(client_.get());
6002 ASSERT_TRUE(CompleteHandshakesForQUIC());
6003
6004 // Both sides can now exchange 1-RTT data.
6005 ExpectHandshakeSuccess();
6006 EXPECT_TRUE(SSL_session_reused(client_.get()));
6007 EXPECT_TRUE(SSL_session_reused(server_.get()));
6008 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6009 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6010 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6011 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6012}
6013
6014TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6015 server_quic_early_data_context_ = {};
6016 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6017
6018 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6019 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6020 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6021 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6022 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6023
6024 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6025 ASSERT_TRUE(session);
6026 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006027}
6028
David Benjamind6343572019-08-15 17:29:02 -04006029TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006030 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006031
6032 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6033 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6034 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6035 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6036 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6037
6038 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6039 ASSERT_TRUE(session);
6040
6041 for (bool reject_hrr : {false, true}) {
6042 SCOPED_TRACE(reject_hrr);
6043
6044 ASSERT_TRUE(CreateClientAndServer());
6045 if (reject_hrr) {
6046 // Configure the server to prefer P-256, which will reject 0-RTT via
6047 // HelloRetryRequest.
6048 int p256 = NID_X9_62_prime256v1;
6049 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6050 } else {
6051 // Disable 0-RTT on the server, so it will reject it.
6052 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006053 }
David Benjamind6343572019-08-15 17:29:02 -04006054 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006055
David Benjamind6343572019-08-15 17:29:02 -04006056 // The client handshake should return immediately into the early data state.
6057 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6058 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6059 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006060 EXPECT_TRUE(
6061 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006062
6063 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006064 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006065 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6066 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6067 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006068 EXPECT_FALSE(
6069 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006070
6071 // The client consumes the server response and signals 0-RTT rejection.
6072 for (;;) {
6073 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6074 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6075 int err = SSL_get_error(client_.get(), -1);
6076 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6077 break;
6078 }
6079 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006080 }
6081
David Benjamind6343572019-08-15 17:29:02 -04006082 // As in TLS over TCP, 0-RTT rejection is sticky.
6083 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6084 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6085
6086 // Finish up the client and server handshakes.
6087 SSL_reset_early_data_reject(client_.get());
6088 ASSERT_TRUE(CompleteHandshakesForQUIC());
6089
6090 // Both sides can now exchange 1-RTT data.
6091 ExpectHandshakeSuccess();
6092 EXPECT_TRUE(SSL_session_reused(client_.get()));
6093 EXPECT_TRUE(SSL_session_reused(server_.get()));
6094 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6095 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6096 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6097 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006098 }
David Benjaminfd863b62019-07-25 13:51:32 -04006099}
6100
David Benjaminee0716f2019-11-19 14:16:28 +08006101TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006102 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006103
6104 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6105 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6106 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6107 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6108 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6109 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6110
6111 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6112 ASSERT_TRUE(session);
6113
6114 ASSERT_TRUE(CreateClientAndServer());
6115 SSL_set_session(client_.get(), session.get());
6116
6117 // Configure the certificate (re)verification to never complete. The client
6118 // handshake should pause.
6119 SSL_set_custom_verify(
6120 client_.get(), SSL_VERIFY_PEER,
6121 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6122 return ssl_verify_retry;
6123 });
6124 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6125 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6126 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6127
6128 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006129 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006130
6131 // After the verification completes, the handshake progresses to the 0-RTT
6132 // point and releases keys.
6133 SSL_set_custom_verify(
6134 client_.get(), SSL_VERIFY_PEER,
6135 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6136 return ssl_verify_ok;
6137 });
6138 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6139 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006140 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006141}
6142
Steven Valdezc8e0f902018-07-14 11:23:01 -04006143// Test only releasing data to QUIC one byte at a time on request, to maximize
6144// state machine pauses. Additionally, test that existing asynchronous callbacks
6145// still work.
6146TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006147 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006148
6149 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6150 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6151 ASSERT_TRUE(CreateClientAndServer());
6152
6153 // Install an asynchronous certificate callback.
6154 bool cert_cb_ok = false;
6155 SSL_set_cert_cb(server_.get(),
6156 [](SSL *, void *arg) -> int {
6157 return *static_cast<bool *>(arg) ? 1 : -1;
6158 },
6159 &cert_cb_ok);
6160
6161 for (;;) {
6162 int client_ret = SSL_do_handshake(client_.get());
6163 if (client_ret != 1) {
6164 ASSERT_EQ(client_ret, -1);
6165 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6166 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6167 }
6168
6169 int server_ret = SSL_do_handshake(server_.get());
6170 if (server_ret != 1) {
6171 ASSERT_EQ(server_ret, -1);
6172 int ssl_err = SSL_get_error(server_.get(), server_ret);
6173 switch (ssl_err) {
6174 case SSL_ERROR_WANT_READ:
6175 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6176 break;
6177 case SSL_ERROR_WANT_X509_LOOKUP:
6178 ASSERT_FALSE(cert_cb_ok);
6179 cert_cb_ok = true;
6180 break;
6181 default:
6182 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6183 }
6184 }
6185
6186 if (client_ret == 1 && server_ret == 1) {
6187 break;
6188 }
6189 }
6190
David Benjamind6343572019-08-15 17:29:02 -04006191 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006192}
6193
6194// Test buffering write data until explicit flushes.
6195TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006196 AllowOutOfOrderWrites();
6197
Steven Valdezc8e0f902018-07-14 11:23:01 -04006198 struct BufferedFlight {
6199 std::vector<uint8_t> data[kNumQUICLevels];
6200 };
6201 static UnownedSSLExData<BufferedFlight> buffered_flights;
6202
David Benjamincc9d9352018-10-30 19:45:22 -05006203 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6204 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006205 BufferedFlight *flight = buffered_flights.Get(ssl);
6206 flight->data[level].insert(flight->data[level].end(), data, data + len);
6207 return 1;
6208 };
6209
6210 auto flush_flight = [](SSL *ssl) -> int {
6211 BufferedFlight *flight = buffered_flights.Get(ssl);
6212 for (size_t level = 0; level < kNumQUICLevels; level++) {
6213 if (!flight->data[level].empty()) {
6214 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6215 static_cast<ssl_encryption_level_t>(level),
6216 flight->data[level])) {
6217 return 0;
6218 }
6219 flight->data[level].clear();
6220 }
6221 }
6222 return 1;
6223 };
6224
David Benjamin1e859052020-02-09 16:04:58 -05006225 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6226 quic_method.add_handshake_data = add_handshake_data;
6227 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006228
6229 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6230 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6231 ASSERT_TRUE(CreateClientAndServer());
6232
6233 BufferedFlight client_flight, server_flight;
6234 buffered_flights.Set(client_.get(), &client_flight);
6235 buffered_flights.Set(server_.get(), &server_flight);
6236
David Benjamind6343572019-08-15 17:29:02 -04006237 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006238
David Benjamind6343572019-08-15 17:29:02 -04006239 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006240}
6241
6242// Test that excess data at one level is rejected. That is, if a single
6243// |SSL_provide_quic_data| call included both ServerHello and
6244// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6245// key change.
6246TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006247 AllowOutOfOrderWrites();
6248
David Benjamincc9d9352018-10-30 19:45:22 -05006249 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6250 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006251 // Switch everything to the initial level.
6252 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6253 MakeConstSpan(data, len));
6254 };
6255
David Benjamin1e859052020-02-09 16:04:58 -05006256 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6257 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006258
6259 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6260 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6261 ASSERT_TRUE(CreateClientAndServer());
6262
6263 // Send the ClientHello and ServerHello through Finished.
6264 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6265 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6266 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6267 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6268 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6269
6270 // The client is still waiting for the ServerHello at initial
6271 // encryption.
6272 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6273
David Benjamincc9d9352018-10-30 19:45:22 -05006274 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6275 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006276 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6277
6278 // The client reads ServerHello successfully, but then rejects the buffered
6279 // EncryptedExtensions on key change.
6280 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6281 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6282 uint32_t err = ERR_get_error();
6283 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006284 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006285
David Benjamin1e859052020-02-09 16:04:58 -05006286 // The client sends an alert in response to this. The alert is sent at
6287 // handshake level because we install write secrets before read secrets and
6288 // the error is discovered when installing the read secret. (How to send
6289 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006290 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006291 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006292 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006293
David Benjamin5298ef92020-03-13 12:17:30 -04006294 // Sanity-check handshake secrets. The error is discovered while setting the
6295 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006296 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006297 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006298}
6299
6300// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6301TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006302 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006303
6304 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6305 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6306 ASSERT_TRUE(CreateClientAndServer());
6307
6308 // Send the ClientHello and ServerHello through Finished.
6309 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6310 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6311 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6312 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6313 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6314
6315 // The client is still waiting for the ServerHello at initial
6316 // encryption.
6317 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6318
6319 // Data cannot be provided at the next level.
6320 std::vector<uint8_t> data;
6321 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006322 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006323 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6324 data.data(), data.size()));
6325 ERR_clear_error();
6326
6327 // Progress to EncryptedExtensions.
6328 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6329 data.data(), data.size()));
6330 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6331 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6332 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6333
6334 // Data cannot be provided at the previous level.
6335 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006336 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006337 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6338 data.data(), data.size()));
6339}
6340
6341TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006342 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006343
6344 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6345 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6346 ASSERT_TRUE(CreateClientAndServer());
6347
6348 size_t limit =
6349 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6350 uint8_t b = 0;
6351 for (size_t i = 0; i < limit; i++) {
6352 ASSERT_TRUE(
6353 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6354 }
6355
6356 EXPECT_FALSE(
6357 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6358}
6359
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006360// Provide invalid post-handshake data.
6361TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006362 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006363
6364 g_last_session = nullptr;
6365
6366 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6367 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6368 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6369 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6370 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006371 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006372
6373 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6374 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006375 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6376 EXPECT_FALSE(transport_->client()->has_alert());
6377 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006378
6379 // Junk sent as part of post-handshake data should cause an error.
6380 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6381 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6382 kJunk, sizeof(kJunk)));
6383 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6384}
6385
Nick Harper80ddfc72020-03-11 18:26:31 -07006386static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6387 Span<const uint8_t> expected) {
6388 const uint8_t *received;
6389 size_t received_len;
6390 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6391 ASSERT_EQ(received_len, expected.size());
6392 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6393}
6394
6395TEST_F(QUICMethodTest, SetTransportParameters) {
6396 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6397 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6398 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6399
6400 ASSERT_TRUE(CreateClientAndServer());
6401 uint8_t kClientParams[] = {1, 2, 3, 4};
6402 uint8_t kServerParams[] = {5, 6, 7};
6403 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6404 sizeof(kClientParams)));
6405 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6406 sizeof(kServerParams)));
6407
6408 ASSERT_TRUE(CompleteHandshakesForQUIC());
6409 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6410 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6411}
6412
6413TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6414 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6415 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6416 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6417
6418 ASSERT_TRUE(CreateClientAndServer());
6419 uint8_t kClientParams[] = {1, 2, 3, 4};
6420 static uint8_t kServerParams[] = {5, 6, 7};
6421 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6422 sizeof(kClientParams)));
6423 SSL_CTX_set_tlsext_servername_callback(
6424 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6425 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6426 sizeof(kServerParams)));
6427 return SSL_TLSEXT_ERR_OK;
6428 });
6429
6430 ASSERT_TRUE(CompleteHandshakesForQUIC());
6431 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6432 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6433}
6434
Nick Harper6bfd25c2020-03-30 17:15:19 -07006435TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6436 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6437
6438 g_last_session = nullptr;
6439
6440 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6441 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6442 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6443 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6444
6445 ASSERT_TRUE(CreateClientAndServer());
6446 ASSERT_TRUE(CompleteHandshakesForQUIC());
6447
6448 ExpectHandshakeSuccess();
6449 EXPECT_FALSE(SSL_session_reused(client_.get()));
6450 EXPECT_FALSE(SSL_session_reused(server_.get()));
6451
6452 // The server sent NewSessionTicket messages in the handshake.
6453 EXPECT_FALSE(g_last_session);
6454 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6455 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6456 EXPECT_TRUE(g_last_session);
6457
6458 // Pretend that g_last_session came from a TLS-over-TCP connection.
6459 g_last_session.get()->is_quic = false;
6460
6461 // Create a second connection and verify that resumption does not occur with
6462 // a session from a non-QUIC connection. This tests that the client does not
6463 // offer over QUIC a session believed to be received over TCP. The server
6464 // believes this is a QUIC session, so if the client offered the session, the
6465 // server would have resumed it.
6466 ASSERT_TRUE(CreateClientAndServer());
6467 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6468 SSL_set_session(client_.get(), session.get());
6469
6470 ASSERT_TRUE(CompleteHandshakesForQUIC());
6471 ExpectHandshakeSuccess();
6472 EXPECT_FALSE(SSL_session_reused(client_.get()));
6473 EXPECT_FALSE(SSL_session_reused(server_.get()));
6474}
6475
6476TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6477 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6478
6479 g_last_session = nullptr;
6480
6481 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6482 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6483 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6484 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6485
6486 ASSERT_TRUE(CreateClientAndServer());
6487 ASSERT_TRUE(CompleteHandshakesForQUIC());
6488
6489 ExpectHandshakeSuccess();
6490 EXPECT_FALSE(SSL_session_reused(client_.get()));
6491 EXPECT_FALSE(SSL_session_reused(server_.get()));
6492
6493 // The server sent NewSessionTicket messages in the handshake.
6494 EXPECT_FALSE(g_last_session);
6495 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6496 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6497 EXPECT_TRUE(g_last_session);
6498
6499 // Attempt a resumption with g_last_session using TLS_method.
6500 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6501 ASSERT_TRUE(client_ctx);
6502
6503 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6504
6505 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6506 server(SSL_new(server_ctx_.get()));
6507 ASSERT_TRUE(client);
6508 ASSERT_TRUE(server);
6509 SSL_set_connect_state(client.get());
6510 SSL_set_accept_state(server.get());
6511
6512 // The TLS-over-TCP client will refuse to resume with a quic session, so
6513 // mark is_quic = false to bypass the client check to test the server check.
6514 g_last_session.get()->is_quic = false;
6515 SSL_set_session(client.get(), g_last_session.get());
6516
6517 BIO *bio1, *bio2;
6518 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6519
6520 // SSL_set_bio takes ownership.
6521 SSL_set_bio(client.get(), bio1, bio1);
6522 SSL_set_bio(server.get(), bio2, bio2);
6523 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6524
6525 EXPECT_FALSE(SSL_session_reused(client.get()));
6526 EXPECT_FALSE(SSL_session_reused(server.get()));
6527}
6528
Nick Harper72cff812020-03-26 18:06:16 -07006529TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6530 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6531 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6532 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6533
6534 ASSERT_TRUE(CreateClientAndServer());
6535 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6536 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6537}
6538
6539TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6540 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6541 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6542 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6543
6544 ASSERT_TRUE(CreateClientAndServer());
6545 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6546 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6547}
6548
David Schinazi3d8b8c32021-01-14 11:25:49 -08006549TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6550 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6551 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6552 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6553
6554 ASSERT_TRUE(CreateClientAndServer());
6555 uint8_t kClientParams[] = {1, 2, 3, 4};
6556 uint8_t kServerParams[] = {5, 6, 7};
6557 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6558 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6559 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6560 sizeof(kClientParams)));
6561 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6562 sizeof(kServerParams)));
6563
6564 ASSERT_TRUE(CompleteHandshakesForQUIC());
6565 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6566 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6567}
6568
6569TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6570 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6571 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6572 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6573
6574 ASSERT_TRUE(CreateClientAndServer());
6575 uint8_t kClientParams[] = {1, 2, 3, 4};
6576 uint8_t kServerParams[] = {5, 6, 7};
6577 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6578 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6579 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6580 sizeof(kClientParams)));
6581 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6582 sizeof(kServerParams)));
6583
6584 ASSERT_TRUE(CompleteHandshakesForQUIC());
6585 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6586 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6587}
6588
6589TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6590 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6591 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6592 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6593
6594 ASSERT_TRUE(CreateClientAndServer());
6595 uint8_t kClientParams[] = {1, 2, 3, 4};
6596 uint8_t kServerParams[] = {5, 6, 7};
6597 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6598 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6599 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6600 sizeof(kClientParams)));
6601 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6602 sizeof(kServerParams)));
6603
6604 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6605}
6606
6607TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6608 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6609 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6610 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6611
6612 ASSERT_TRUE(CreateClientAndServer());
6613 uint8_t kClientParams[] = {1, 2, 3, 4};
6614 uint8_t kServerParams[] = {5, 6, 7};
6615 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6616 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6617 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6618 sizeof(kClientParams)));
6619 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6620 sizeof(kServerParams)));
6621
6622 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6623}
6624
David Benjaminc47bfce2021-01-20 17:10:32 -05006625// Test that the default QUIC code point is consistent with
6626// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6627// update the two values together.
6628TEST_F(QUICMethodTest, QuicCodePointDefault) {
6629 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6630 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6631 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6632 SSL_CTX_set_select_certificate_cb(
6633 server_ctx_.get(),
6634 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6635 const uint8_t *data;
6636 size_t len;
6637 if (!SSL_early_callback_ctx_extension_get(
6638 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6639 &len)) {
6640 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6641 return ssl_select_cert_error;
6642 }
6643 return ssl_select_cert_success;
6644 });
6645
6646 ASSERT_TRUE(CreateClientAndServer());
6647 ASSERT_TRUE(CompleteHandshakesForQUIC());
6648}
6649
Adam Langley7540cc22019-04-18 09:56:13 -07006650extern "C" {
6651int BORINGSSL_enum_c_type_test(void);
6652}
6653
6654TEST(SSLTest, EnumTypes) {
6655 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6656 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6657}
6658
David Benjaminb29e1e12019-05-06 14:44:46 -05006659TEST_P(SSLVersionTest, DoubleSSLError) {
6660 // Connect the inner SSL connections.
6661 ASSERT_TRUE(Connect());
6662
6663 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6664 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6665 ASSERT_TRUE(bio_method);
6666 ASSERT_TRUE(BIO_meth_set_read(
6667 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6668 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6669 int ret = SSL_read(ssl, out, len);
6670 int ssl_ret = SSL_get_error(ssl, ret);
6671 if (ssl_ret == SSL_ERROR_WANT_READ) {
6672 BIO_set_retry_read(bio);
6673 }
6674 return ret;
6675 }));
6676 ASSERT_TRUE(BIO_meth_set_write(
6677 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6678 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6679 int ret = SSL_write(ssl, in, len);
6680 int ssl_ret = SSL_get_error(ssl, ret);
6681 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6682 BIO_set_retry_write(bio);
6683 }
6684 return ret;
6685 }));
6686 ASSERT_TRUE(BIO_meth_set_ctrl(
6687 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6688 // |SSL| objects require |BIO_flush| support.
6689 if (cmd == BIO_CTRL_FLUSH) {
6690 return 1;
6691 }
6692 return 0;
6693 }));
6694
6695 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6696 ASSERT_TRUE(client_bio);
6697 BIO_set_data(client_bio.get(), client_.get());
6698 BIO_set_init(client_bio.get(), 1);
6699
6700 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6701 ASSERT_TRUE(server_bio);
6702 BIO_set_data(server_bio.get(), server_.get());
6703 BIO_set_init(server_bio.get(), 1);
6704
6705 // Wrap the inner connections in another layer of SSL.
6706 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6707 ASSERT_TRUE(client_outer);
6708 SSL_set_connect_state(client_outer.get());
6709 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6710 client_bio.release(); // |SSL_set_bio| takes ownership.
6711
6712 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6713 ASSERT_TRUE(server_outer);
6714 SSL_set_accept_state(server_outer.get());
6715 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6716 server_bio.release(); // |SSL_set_bio| takes ownership.
6717
6718 // Configure |client_outer| to reject the server certificate.
6719 SSL_set_custom_verify(
6720 client_outer.get(), SSL_VERIFY_PEER,
6721 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6722 return ssl_verify_invalid;
6723 });
6724
6725 for (;;) {
6726 int client_ret = SSL_do_handshake(client_outer.get());
6727 int client_err = SSL_get_error(client_outer.get(), client_ret);
6728 if (client_err != SSL_ERROR_WANT_READ &&
6729 client_err != SSL_ERROR_WANT_WRITE) {
6730 // The client handshake should terminate on a certificate verification
6731 // error.
6732 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6733 uint32_t err = ERR_peek_error();
6734 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6735 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6736 break;
6737 }
6738
6739 // Run the server handshake and continue.
6740 int server_ret = SSL_do_handshake(server_outer.get());
6741 int server_err = SSL_get_error(server_outer.get(), server_ret);
6742 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6743 server_err == SSL_ERROR_WANT_READ ||
6744 server_err == SSL_ERROR_WANT_WRITE);
6745 }
6746}
6747
David Benjamin1b819472020-06-09 14:01:02 -04006748TEST_P(SSLVersionTest, SameKeyResume) {
6749 uint8_t key[48];
6750 RAND_bytes(key, sizeof(key));
6751
6752 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6753 ASSERT_TRUE(server_ctx2);
6754 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6755 ASSERT_TRUE(
6756 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6757 ASSERT_TRUE(
6758 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6759
6760 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6761 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6762 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6763
6764 // Establish a session for |server_ctx_|.
6765 bssl::UniquePtr<SSL_SESSION> session =
6766 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6767 ASSERT_TRUE(session);
6768 ClientConfig config;
6769 config.session = session.get();
6770
6771 // Resuming with |server_ctx_| again works.
6772 bssl::UniquePtr<SSL> client, server;
6773 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6774 server_ctx_.get(), config));
6775 EXPECT_TRUE(SSL_session_reused(client.get()));
6776 EXPECT_TRUE(SSL_session_reused(server.get()));
6777
6778 // Resuming with |server_ctx2| also works.
6779 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6780 server_ctx2.get(), config));
6781 EXPECT_TRUE(SSL_session_reused(client.get()));
6782 EXPECT_TRUE(SSL_session_reused(server.get()));
6783}
6784
6785TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6786 uint8_t key1[48], key2[48];
6787 RAND_bytes(key1, sizeof(key1));
6788 RAND_bytes(key2, sizeof(key2));
6789
6790 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6791 ASSERT_TRUE(server_ctx2);
6792 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6793 ASSERT_TRUE(
6794 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
6795 ASSERT_TRUE(
6796 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
6797
6798 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6799 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6800 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6801
6802 // Establish a session for |server_ctx_|.
6803 bssl::UniquePtr<SSL_SESSION> session =
6804 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6805 ASSERT_TRUE(session);
6806 ClientConfig config;
6807 config.session = session.get();
6808
6809 // Resuming with |server_ctx_| again works.
6810 bssl::UniquePtr<SSL> client, server;
6811 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6812 server_ctx_.get(), config));
6813 EXPECT_TRUE(SSL_session_reused(client.get()));
6814 EXPECT_TRUE(SSL_session_reused(server.get()));
6815
6816 // Resuming with |server_ctx2| does not work.
6817 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6818 server_ctx2.get(), config));
6819 EXPECT_FALSE(SSL_session_reused(client.get()));
6820 EXPECT_FALSE(SSL_session_reused(server.get()));
6821}
6822
6823TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
6824 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6825 ASSERT_TRUE(server_ctx2);
6826 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6827
6828 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6829 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6830 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6831
6832 // Establish a session for |server_ctx_|.
6833 bssl::UniquePtr<SSL_SESSION> session =
6834 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6835 ASSERT_TRUE(session);
6836 ClientConfig config;
6837 config.session = session.get();
6838
6839 // Resuming with |server_ctx_| again works.
6840 bssl::UniquePtr<SSL> client, server;
6841 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6842 server_ctx_.get(), config));
6843 EXPECT_TRUE(SSL_session_reused(client.get()));
6844 EXPECT_TRUE(SSL_session_reused(server.get()));
6845
6846 // Resuming with |server_ctx2| does not work.
6847 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6848 server_ctx2.get(), config));
6849 EXPECT_FALSE(SSL_session_reused(client.get()));
6850 EXPECT_FALSE(SSL_session_reused(server.get()));
6851}
6852
Adam Langley47cefed2021-05-26 13:36:40 -07006853Span<const uint8_t> SessionIDOf(const SSL* ssl) {
6854 const SSL_SESSION *session = SSL_get_session(ssl);
6855 unsigned len;
6856 const uint8_t *data = SSL_SESSION_get_id(session, &len);
6857 return MakeConstSpan(data, len);
6858}
6859
6860TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
6861 // This checks that the session IDs at client and server match after a ticket
6862 // resumption. It's unclear whether this should be true, but Envoy depends
6863 // on it in their tests so this will give an early signal if we break it.
6864 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6865 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6866
6867 bssl::UniquePtr<SSL_SESSION> session =
6868 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6869
6870 bssl::UniquePtr<SSL> client, server;
6871 ClientConfig config;
6872 config.session = session.get();
6873 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6874 server_ctx_.get(), config));
6875 EXPECT_TRUE(SSL_session_reused(client.get()));
6876 EXPECT_TRUE(SSL_session_reused(server.get()));
6877
6878 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
6879}
6880
David Benjamin0e7dbd52019-05-15 16:01:18 -04006881TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04006882 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006883 ASSERT_TRUE(ctx);
6884
David Benjamin0e7dbd52019-05-15 16:01:18 -04006885 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
6886 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
6887 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6888 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
6889
6890 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006891 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006892 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04006893 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006894
6895 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
6896
6897 // Write "hello" until the buffer is full, so |client| has a pending write.
6898 size_t num_writes = 0;
6899 for (;;) {
6900 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
6901 if (ret != int(sizeof(kInput))) {
6902 ASSERT_EQ(-1, ret);
6903 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
6904 break;
6905 }
6906 num_writes++;
6907 }
6908
6909 // Encrypt a HelloRequest.
6910 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
6911#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
6912 // Fuzzer-mode records are unencrypted.
6913 uint8_t record[5 + sizeof(in)];
6914 record[0] = SSL3_RT_HANDSHAKE;
6915 record[1] = 3;
6916 record[2] = 3; // TLS 1.2
6917 record[3] = 0;
6918 record[4] = sizeof(record) - 5;
6919 memcpy(record + 5, in, sizeof(in));
6920#else
6921 // Extract key material from |server|.
6922 static const size_t kKeyLen = 32;
6923 static const size_t kNonceLen = 12;
6924 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
6925 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
6926 ASSERT_TRUE(
6927 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
6928 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
6929 Span<uint8_t> nonce =
6930 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
6931
6932 uint8_t ad[13];
6933 uint64_t seq = SSL_get_write_sequence(server.get());
6934 for (size_t i = 0; i < 8; i++) {
6935 // The nonce is XORed with the sequence number.
6936 nonce[11 - i] ^= uint8_t(seq);
6937 ad[7 - i] = uint8_t(seq);
6938 seq >>= 8;
6939 }
6940
6941 ad[8] = SSL3_RT_HANDSHAKE;
6942 ad[9] = 3;
6943 ad[10] = 3; // TLS 1.2
6944 ad[11] = 0;
6945 ad[12] = sizeof(in);
6946
6947 uint8_t record[5 + sizeof(in) + 16];
6948 record[0] = SSL3_RT_HANDSHAKE;
6949 record[1] = 3;
6950 record[2] = 3; // TLS 1.2
6951 record[3] = 0;
6952 record[4] = sizeof(record) - 5;
6953
6954 ScopedEVP_AEAD_CTX aead;
6955 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
6956 key.data(), key.size(),
6957 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
6958 size_t len;
6959 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
6960 sizeof(record) - 5, nonce.data(), nonce.size(),
6961 in, sizeof(in), ad, sizeof(ad)));
6962 ASSERT_EQ(sizeof(record) - 5, len);
6963#endif // BORINGSSL_UNSAFE_FUZZER_MODE
6964
6965 ASSERT_EQ(int(sizeof(record)),
6966 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
6967
6968 // |SSL_read| should pick up the HelloRequest.
6969 uint8_t byte;
6970 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6971 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6972
6973 // Drain the data from the |client|.
6974 uint8_t buf[sizeof(kInput)];
6975 for (size_t i = 0; i < num_writes; i++) {
6976 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6977 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6978 }
6979
6980 // |client| should be able to finish the pending write and continue to write,
6981 // despite the paused HelloRequest.
6982 ASSERT_EQ(int(sizeof(kInput)),
6983 SSL_write(client.get(), kInput, sizeof(kInput)));
6984 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6985 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6986
6987 ASSERT_EQ(int(sizeof(kInput)),
6988 SSL_write(client.get(), kInput, sizeof(kInput)));
6989 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6990 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6991
6992 // |SSL_read| is stuck until we acknowledge the HelloRequest.
6993 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6994 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6995
6996 ASSERT_TRUE(SSL_renegotiate(client.get()));
6997 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6998 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
6999
7000 // We never renegotiate as a server.
7001 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7002 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7003 uint32_t err = ERR_get_error();
7004 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7005 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7006}
7007
David Benjaminf9e0cda2020-03-23 18:29:09 -04007008
7009TEST(SSLTest, CopyWithoutEarlyData) {
7010 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007011 bssl::UniquePtr<SSL_CTX> server_ctx(
7012 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007013 ASSERT_TRUE(client_ctx);
7014 ASSERT_TRUE(server_ctx);
7015
David Benjaminf9e0cda2020-03-23 18:29:09 -04007016 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7017 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7018 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7019 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7020
7021 bssl::UniquePtr<SSL_SESSION> session =
7022 CreateClientSession(client_ctx.get(), server_ctx.get());
7023 ASSERT_TRUE(session);
7024
7025 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007026 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007027 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7028 server_ctx.get()));
7029 SSL_set_session(client.get(), session.get());
7030 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007031 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7032 EXPECT_TRUE(SSL_in_early_data(client.get()));
7033
7034 // |SSL_SESSION_copy_without_early_data| should disable early data but
7035 // still resume the session.
7036 bssl::UniquePtr<SSL_SESSION> session2(
7037 SSL_SESSION_copy_without_early_data(session.get()));
7038 ASSERT_TRUE(session2);
7039 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007040 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7041 server_ctx.get()));
7042 SSL_set_session(client.get(), session2.get());
7043 SSL_set_early_data_enabled(client.get(), 1);
7044 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007045 EXPECT_TRUE(SSL_session_reused(client.get()));
7046 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7047 SSL_get_early_data_reason(client.get()));
7048
7049 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7050 // when passed an early-data-incapable session.
7051 bssl::UniquePtr<SSL_SESSION> session3(
7052 SSL_SESSION_copy_without_early_data(session2.get()));
7053 EXPECT_EQ(session2.get(), session3.get());
7054}
7055
Adam Langley53a17f52020-05-26 14:44:07 -07007056TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7057 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007058 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007059 bssl::UniquePtr<SSL_CTX> server_ctx(
7060 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007061 ASSERT_TRUE(client_ctx);
7062 ASSERT_TRUE(server_ctx);
7063 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7064 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7065 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7066 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007067
7068 bssl::UniquePtr<SSL> client, server;
7069 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7070 server_ctx.get()));
7071 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7072
7073 // Process a TLS 1.3 NewSessionTicket.
7074 static const uint8_t kTicket[] = {
7075 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7076 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7077 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7078 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7079 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7080 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7081 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7082 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7083 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7084 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7085 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7086 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7087 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7088 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7089 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7090 0x00, 0x00,
7091 };
7092 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7093 client.get(), kTicket, sizeof(kTicket)));
7094 ASSERT_TRUE(session);
7095 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7096
7097 uint8_t *session_buf = nullptr;
7098 size_t session_length = 0;
7099 ASSERT_TRUE(
7100 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7101 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7102 ASSERT_TRUE(session_buf);
7103 ASSERT_GT(session_length, 0u);
7104
7105 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7106 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7107 sizeof(kTicket)));
7108
7109 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7110 // handshake completes.
7111 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7112 ASSERT_TRUE(client2);
7113 SSL_set_connect_state(client2.get());
7114 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7115 sizeof(kTicket)));
7116}
7117
David Benjamin3989c992020-10-09 14:12:06 -04007118TEST(SSLTest, BIO) {
7119 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007120 bssl::UniquePtr<SSL_CTX> server_ctx(
7121 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007122 ASSERT_TRUE(client_ctx);
7123 ASSERT_TRUE(server_ctx);
7124
David Benjamin3989c992020-10-09 14:12:06 -04007125 for (bool take_ownership : {true, false}) {
7126 // For simplicity, get the handshake out of the way first.
7127 bssl::UniquePtr<SSL> client, server;
7128 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7129 server_ctx.get()));
7130
7131 // Wrap |client| in an SSL BIO.
7132 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7133 ASSERT_TRUE(client_bio);
7134 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7135 if (take_ownership) {
7136 client.release();
7137 }
7138
7139 // Flushing the BIO should not crash.
7140 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7141
7142 // Exchange some data.
7143 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7144 uint8_t buf[5];
7145 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7146 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7147
7148 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7149 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7150 EXPECT_EQ(Bytes("world"), Bytes(buf));
7151
7152 // |BIO_should_read| should work.
7153 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7154 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7155
7156 // Writing data should eventually exceed the buffer size and fail, reporting
7157 // |BIO_should_write|.
7158 int ret;
7159 for (int i = 0; i < 1024; i++) {
7160 std::vector<uint8_t> buffer(1024);
7161 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7162 if (ret <= 0) {
7163 break;
7164 }
7165 }
7166 EXPECT_EQ(-1, ret);
7167 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7168 }
7169}
7170
David Benjamin12a3e7e2021-04-13 11:47:36 -04007171TEST(SSLTest, ALPNConfig) {
7172 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7173 ASSERT_TRUE(ctx);
7174 bssl::UniquePtr<X509> cert = GetTestCertificate();
7175 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7176 ASSERT_TRUE(cert);
7177 ASSERT_TRUE(key);
7178 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7179 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7180
7181 // Set up some machinery to check the configured ALPN against what is actually
7182 // sent over the wire. Note that the ALPN callback is only called when the
7183 // client offers ALPN.
7184 std::vector<uint8_t> observed_alpn;
7185 SSL_CTX_set_alpn_select_cb(
7186 ctx.get(),
7187 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7188 unsigned in_len, void *arg) -> int {
7189 std::vector<uint8_t> *observed_alpn_ptr =
7190 static_cast<std::vector<uint8_t> *>(arg);
7191 observed_alpn_ptr->assign(in, in + in_len);
7192 return SSL_TLSEXT_ERR_NOACK;
7193 },
7194 &observed_alpn);
7195 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7196 observed_alpn.clear();
7197 bssl::UniquePtr<SSL> client, server;
7198 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7199 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7200 };
7201
7202 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7203 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7204 0x03, 'b', 'a', 'r'};
7205 EXPECT_EQ(0,
7206 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7207 check_alpn_proto(kValidList);
7208
7209 // Invalid lists are rejected.
7210 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7211 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7212 sizeof(kInvalidList)));
7213
7214 // Empty lists are valid and are interpreted as disabling ALPN.
7215 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7216 check_alpn_proto({});
7217}
7218
David Benjamin2f3958a2021-04-16 11:55:23 -04007219// Test that the key usage checker can correctly handle issuerUID and
7220// subjectUID. See https://crbug.com/1199744.
7221TEST(SSLTest, KeyUsageWithUIDs) {
7222 static const char kGoodKeyUsage[] = R"(
7223-----BEGIN CERTIFICATE-----
7224MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7225AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7226aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7227CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7228ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
72294r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7230Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7231ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7232A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
723334EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
72344Z7qDhjIhiF4dM0uEDYRVA==
7235-----END CERTIFICATE-----
7236)";
7237 static const char kBadKeyUsage[] = R"(
7238-----BEGIN CERTIFICATE-----
7239MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7240AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7241aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7242CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7243ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
72444r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7245Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7246ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7247A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7248taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7249RHrQbWsFUakETXL9QMlegh5t
7250-----END CERTIFICATE-----
7251)";
7252
7253 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7254 ASSERT_TRUE(good);
7255 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7256 ASSERT_TRUE(bad);
7257
7258 // We check key usage when configuring EC certificates to distinguish ECDSA
7259 // and ECDH.
7260 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7261 ASSERT_TRUE(ctx);
7262 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7263 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7264}
7265
David Benjamin9b2cdb72021-04-01 23:21:53 -04007266// Test that |SSL_can_release_private_key| reports true as early as expected.
7267// The internal asserts in the library check we do not report true too early.
7268TEST(SSLTest, CanReleasePrivateKey) {
7269 bssl::UniquePtr<SSL_CTX> client_ctx =
7270 CreateContextWithTestCertificate(TLS_method());
7271 ASSERT_TRUE(client_ctx);
7272 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7273
7274 // Note this assumes the transport buffer is large enough to fit the client
7275 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7276 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7277 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7278 // Write the ClientHello.
7279 ASSERT_EQ(-1, SSL_do_handshake(client));
7280 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7281
7282 // Consume the ClientHello and write the server flight.
7283 ASSERT_EQ(-1, SSL_do_handshake(server));
7284 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7285
7286 EXPECT_TRUE(SSL_can_release_private_key(server));
7287 };
7288
7289 {
7290 SCOPED_TRACE("TLS 1.2 ECDHE");
7291 bssl::UniquePtr<SSL_CTX> server_ctx(
7292 CreateContextWithTestCertificate(TLS_method()));
7293 ASSERT_TRUE(server_ctx);
7294 ASSERT_TRUE(
7295 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7296 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7297 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7298 // Configure the server to request client certificates, so we can also test
7299 // the client half.
7300 SSL_CTX_set_custom_verify(
7301 server_ctx.get(), SSL_VERIFY_PEER,
7302 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7303 bssl::UniquePtr<SSL> client, server;
7304 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7305 server_ctx.get()));
7306 check_first_server_round_trip(client.get(), server.get());
7307
7308 // Consume the server flight and write the client response. The client still
7309 // has a Finished message to consume but can also release its key early.
7310 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7311 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7312 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7313
7314 // However, a client that has not disabled renegotiation can never release
7315 // the key.
7316 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7317 server_ctx.get()));
7318 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7319 check_first_server_round_trip(client.get(), server.get());
7320 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7321 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7322 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7323 }
7324
7325 {
7326 SCOPED_TRACE("TLS 1.2 resumption");
7327 bssl::UniquePtr<SSL_CTX> server_ctx(
7328 CreateContextWithTestCertificate(TLS_method()));
7329 ASSERT_TRUE(server_ctx);
7330 ASSERT_TRUE(
7331 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7332 bssl::UniquePtr<SSL_SESSION> session =
7333 CreateClientSession(client_ctx.get(), server_ctx.get());
7334 ASSERT_TRUE(session);
7335 bssl::UniquePtr<SSL> client, server;
7336 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7337 server_ctx.get()));
7338 SSL_set_session(client.get(), session.get());
7339 check_first_server_round_trip(client.get(), server.get());
7340 }
7341
7342 {
7343 SCOPED_TRACE("TLS 1.3 1-RTT");
7344 bssl::UniquePtr<SSL_CTX> server_ctx(
7345 CreateContextWithTestCertificate(TLS_method()));
7346 ASSERT_TRUE(server_ctx);
7347 ASSERT_TRUE(
7348 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7349 bssl::UniquePtr<SSL> client, server;
7350 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7351 server_ctx.get()));
7352 check_first_server_round_trip(client.get(), server.get());
7353 }
7354
7355 {
7356 SCOPED_TRACE("TLS 1.3 resumption");
7357 bssl::UniquePtr<SSL_CTX> server_ctx(
7358 CreateContextWithTestCertificate(TLS_method()));
7359 ASSERT_TRUE(server_ctx);
7360 ASSERT_TRUE(
7361 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7362 bssl::UniquePtr<SSL_SESSION> session =
7363 CreateClientSession(client_ctx.get(), server_ctx.get());
7364 ASSERT_TRUE(session);
7365 bssl::UniquePtr<SSL> client, server;
7366 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7367 server_ctx.get()));
7368 SSL_set_session(client.get(), session.get());
7369 check_first_server_round_trip(client.get(), server.get());
7370 }
7371}
7372
David Benjamine9c5d722021-06-09 17:43:16 -04007373// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7374// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7375// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7376// will be set to the ClientHelloInner's extensions, rather than
7377// ClientHelloOuter.
7378static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7379 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7380 struct AppData {
7381 std::vector<uint16_t> *out;
7382 bool decrypt_ech;
7383 bool callback_done = false;
7384 };
7385 AppData app_data;
7386 app_data.out = out;
7387 app_data.decrypt_ech = decrypt_ech;
7388
7389 bssl::UniquePtr<SSL_CTX> server_ctx =
7390 CreateContextWithTestCertificate(TLS_method());
7391 if (!server_ctx || //
7392 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7393 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7394 return false;
7395 }
7396
7397 // Configure the server to record the ClientHello extension order. We use a
7398 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7399 SSL_CTX_set_select_certificate_cb(
7400 server_ctx.get(),
7401 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7402 AppData *app_data_ptr = static_cast<AppData *>(
7403 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7404 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7405 SSL_ech_accepted(client_hello->ssl));
7406
7407 app_data_ptr->out->clear();
7408 CBS extensions;
7409 CBS_init(&extensions, client_hello->extensions,
7410 client_hello->extensions_len);
7411 while (CBS_len(&extensions)) {
7412 uint16_t type;
7413 CBS body;
7414 if (!CBS_get_u16(&extensions, &type) ||
7415 !CBS_get_u16_length_prefixed(&extensions, &body)) {
7416 return ssl_select_cert_error;
7417 }
7418 app_data_ptr->out->push_back(type);
7419 }
7420
7421 // Don't bother completing the handshake.
7422 app_data_ptr->callback_done = true;
7423 return ssl_select_cert_error;
7424 });
7425
7426 bssl::UniquePtr<SSL> client, server;
7427 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
7428 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
7429 return false;
7430 }
7431
7432 // Run the handshake far enough to process the ClientHello.
7433 SSL_do_handshake(client.get());
7434 SSL_do_handshake(server.get());
7435 return app_data.callback_done;
7436}
7437
7438// Test that, when extension permutation is enabled, the ClientHello extension
7439// order changes, both with and without ECH, and in both ClientHelloInner and
7440// ClientHelloOuter.
7441TEST(SSLTest, PermuteExtensions) {
7442 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
7443 ASSERT_TRUE(keys);
7444 for (bool offer_ech : {false, true}) {
7445 SCOPED_TRACE(offer_ech);
7446 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
7447 for (bool decrypt_ech : {false, true}) {
7448 SCOPED_TRACE(decrypt_ech);
7449 if (!offer_ech && decrypt_ech) {
7450 continue;
7451 }
7452
7453 // When extension permutation is disabled, the order should be consistent.
7454 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7455 ASSERT_TRUE(ctx);
7456 std::vector<uint16_t> order1, order2;
7457 ASSERT_TRUE(
7458 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7459 ASSERT_TRUE(
7460 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7461 EXPECT_EQ(order1, order2);
7462
7463 ctx.reset(SSL_CTX_new(TLS_method()));
7464 ASSERT_TRUE(ctx);
7465 SSL_CTX_set_permute_extensions(ctx.get(), 1);
7466
7467 // When extension permutation is enabled, each ClientHello should have a
7468 // different order.
7469 //
7470 // This test is inherently flaky, so we run it multiple times. We send at
7471 // least five extensions by default from TLS 1.3: supported_versions,
7472 // key_share, supported_groups, psk_key_exchange_modes, and
7473 // signature_algorithms. That means the probability of a false negative is
7474 // at most 1/120. Repeating the test 14 times lowers false negative rate
7475 // to under 2^-96.
7476 ASSERT_TRUE(
7477 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7478 EXPECT_GE(order1.size(), 5u);
7479 static const int kNumIterations = 14;
7480 bool passed = false;
7481 for (int i = 0; i < kNumIterations; i++) {
7482 ASSERT_TRUE(
7483 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7484 if (order1 != order2) {
7485 passed = true;
7486 break;
7487 }
7488 }
7489 EXPECT_TRUE(passed) << "Extensions were not permuted";
7490 }
7491 }
7492}
7493
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007494} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007495BSSL_NAMESPACE_END