blob: 9247dc33a3dd0932d4ddf67db5de414ab6869ab1 [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
David Benjamina4385192023-03-25 01:26:49 -040015#include <limits.h>
David Benjamin2e521212014-07-16 14:37:51 -040016#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040017#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040018#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040019
David Benjamin0f653952015-10-18 14:28:01 -040020#include <algorithm>
Steven Valdezc8e0f902018-07-14 11:23:01 -040021#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050023#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040024#include <vector>
25
David Benjamin96628432017-01-19 19:05:47 -050026#include <gtest/gtest.h>
27
David Benjamin0e7dbd52019-05-15 16:01:18 -040028#include <openssl/aead.h>
David Benjamin751e8892014-10-19 00:59:36 -040029#include <openssl/base64.h>
David Benjamine9c5d722021-06-09 17:43:16 -040030#include <openssl/bytestring.h>
David Benjamin751e8892014-10-19 00:59:36 -040031#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040032#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040033#include <openssl/crypto.h>
Daniel McArdle00e434d2021-02-18 11:47:18 -050034#include <openssl/curve25519.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040036#include <openssl/hmac.h>
David Benjaminc890ae52021-06-06 13:32:29 -040037#include <openssl/hpke.h>
David Benjaminde942382016-02-11 12:02:01 -050038#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040039#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040040#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040041#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050042#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040043
Steven Valdez87eab492016-06-27 16:34:59 -040044#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040045#include "../crypto/internal.h"
David Benjamin0ff377a2024-02-03 09:47:19 -050046#include "../crypto/test/file_util.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020047#include "../crypto/test/test_util.h"
48
David Benjamin721e8b72016-08-03 13:13:17 -040049#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040050// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040051OPENSSL_MSVC_PRAGMA(warning(push, 3))
52#include <winsock2.h>
53OPENSSL_MSVC_PRAGMA(warning(pop))
54#else
55#include <sys/time.h>
56#endif
57
David Benjamin5b33eff2018-09-22 16:52:48 -070058#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040059#include <thread>
60#endif
61
David Benjamin1d77e562015-03-22 17:22:08 -040062
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070063BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070064
65namespace {
66
Martin Kreichgauer1a663262017-08-16 14:54:04 -070067#define TRACED_CALL(code) \
68 do { \
69 SCOPED_TRACE("<- called from here"); \
70 code; \
71 if (::testing::Test::HasFatalFailure()) { \
72 return; \
73 } \
74 } while (false)
75
Martin Kreichgauer72912d22017-08-04 12:06:43 -070076struct VersionParam {
77 uint16_t version;
78 enum { is_tls, is_dtls } ssl_method;
79 const char name[8];
80};
81
82static const size_t kTicketKeyLen = 48;
83
84static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070085 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
86 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
87 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070088 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070089 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
90 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
91};
92
David Benjamin1d77e562015-03-22 17:22:08 -040093struct ExpectedCipher {
94 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040095 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040096};
David Benjaminbb0a17c2014-09-20 15:35:39 -040097
David Benjamin1d77e562015-03-22 17:22:08 -040098struct CipherTest {
99 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400100 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -0500101 // The list of expected ciphers, in order.
102 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800103 // True if this cipher list should fail in strict mode.
104 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400105};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400106
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100107struct CurveTest {
108 // The rule string to apply.
109 const char *rule;
110 // The list of expected curves, in order.
111 std::vector<uint16_t> expected;
112};
113
Steven Valdezc8e0f902018-07-14 11:23:01 -0400114template <typename T>
115class UnownedSSLExData {
116 public:
117 UnownedSSLExData() {
118 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
119 }
120
121 T *Get(const SSL *ssl) {
122 return index_ < 0 ? nullptr
123 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
124 }
125
126 bool Set(SSL *ssl, T *t) {
127 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
128 }
129
130 private:
131 int index_;
132};
133
David Benjaminfb974e62015-12-16 19:34:22 -0500134static const CipherTest kCipherTests[] = {
135 // Selecting individual ciphers should work.
136 {
137 "ECDHE-ECDSA-CHACHA20-POLY1305:"
138 "ECDHE-RSA-CHACHA20-POLY1305:"
139 "ECDHE-ECDSA-AES128-GCM-SHA256:"
140 "ECDHE-RSA-AES128-GCM-SHA256",
141 {
142 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500143 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500144 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
145 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
146 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800147 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500148 },
149 // + reorders selected ciphers to the end, keeping their relative order.
150 {
151 "ECDHE-ECDSA-CHACHA20-POLY1305:"
152 "ECDHE-RSA-CHACHA20-POLY1305:"
153 "ECDHE-ECDSA-AES128-GCM-SHA256:"
154 "ECDHE-RSA-AES128-GCM-SHA256:"
155 "+aRSA",
156 {
157 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500158 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
159 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500160 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
161 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800162 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500163 },
164 // ! banishes ciphers from future selections.
165 {
166 "!aRSA:"
167 "ECDHE-ECDSA-CHACHA20-POLY1305:"
168 "ECDHE-RSA-CHACHA20-POLY1305:"
169 "ECDHE-ECDSA-AES128-GCM-SHA256:"
170 "ECDHE-RSA-AES128-GCM-SHA256",
171 {
172 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500173 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
174 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800175 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500176 },
177 // Multiple masks can be ANDed in a single rule.
178 {
179 "kRSA+AESGCM+AES128",
180 {
181 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
182 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800183 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500184 },
185 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700186 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500187 // ECDHE_RSA.
188 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700189 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700190 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500191 "AESGCM+AES128+aRSA",
192 {
193 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500194 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
195 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800196 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500197 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800198 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500199 {
200 "ECDHE-ECDSA-CHACHA20-POLY1305:"
201 "ECDHE-RSA-CHACHA20-POLY1305:"
202 "ECDHE-ECDSA-AES128-GCM-SHA256:"
203 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800204 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500205 {
206 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500207 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500208 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
209 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
210 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800211 true,
212 },
213 // Unknown selectors are no-ops, except in strict mode.
214 {
215 "ECDHE-ECDSA-CHACHA20-POLY1305:"
216 "ECDHE-RSA-CHACHA20-POLY1305:"
217 "ECDHE-ECDSA-AES128-GCM-SHA256:"
218 "ECDHE-RSA-AES128-GCM-SHA256:"
219 "-BOGUS2:+BOGUS3:!BOGUS4",
220 {
221 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
222 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
223 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
224 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
225 },
226 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500227 },
228 // Square brackets specify equi-preference groups.
229 {
230 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
231 "[ECDHE-RSA-CHACHA20-POLY1305]:"
232 "ECDHE-RSA-AES128-GCM-SHA256",
233 {
234 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500235 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800236 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500237 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
238 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800239 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500240 },
David Benjamin6fff3862017-06-21 21:07:04 -0400241 // Standard names may be used instead of OpenSSL names.
242 {
243 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400244 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400245 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
246 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
247 {
248 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
249 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
250 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
251 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
252 },
253 false,
254 },
David Benjaminfb974e62015-12-16 19:34:22 -0500255 // @STRENGTH performs a stable strength-sort of the selected ciphers and
256 // only the selected ciphers.
257 {
258 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700259 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400260 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500261 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700262 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500263 // Select ECDHE ones and sort them by strength. Ties should resolve
264 // based on the order above.
265 "kECDHE:@STRENGTH:-ALL:"
266 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
267 // by strength. Then RSA, backwards by strength.
268 "aRSA",
269 {
270 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
271 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500272 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500273 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
274 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
275 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800276 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500277 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400278 // Additional masks after @STRENGTH get silently discarded.
279 //
280 // TODO(davidben): Make this an error. If not silently discarded, they get
281 // interpreted as + opcodes which are very different.
282 {
283 "ECDHE-RSA-AES128-GCM-SHA256:"
284 "ECDHE-RSA-AES256-GCM-SHA384:"
285 "@STRENGTH+AES256",
286 {
287 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
288 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
289 },
290 false,
291 },
292 {
293 "ECDHE-RSA-AES128-GCM-SHA256:"
294 "ECDHE-RSA-AES256-GCM-SHA384:"
295 "@STRENGTH+AES256:"
296 "ECDHE-RSA-CHACHA20-POLY1305",
297 {
298 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
299 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
300 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
301 },
302 false,
303 },
David Benjaminfb974e62015-12-16 19:34:22 -0500304 // Exact ciphers may not be used in multi-part rules; they are treated
305 // as unknown aliases.
306 {
307 "ECDHE-ECDSA-AES128-GCM-SHA256:"
308 "ECDHE-RSA-AES128-GCM-SHA256:"
309 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
310 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
311 {
312 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
313 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
314 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800315 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500316 },
317 // SSLv3 matches everything that existed before TLS 1.2.
318 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400319 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500320 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400321 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500322 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800323 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500324 },
325 // TLSv1.2 matches everything added in TLS 1.2.
326 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400327 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500328 {
329 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
330 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800331 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500332 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800333 // The two directives have no intersection. But each component is valid, so
334 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500335 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400336 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500337 {
338 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400339 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500340 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800341 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500342 },
Adam Langley22df6912017-07-25 12:27:37 -0700343 // Spaces, semi-colons and commas are separators.
344 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400345 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700346 {
347 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400348 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700349 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400350 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700351 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
352 },
353 // …but not in strict mode.
354 true,
355 },
David Benjaminb0251b12023-04-21 17:56:08 -0400356 // 3DES ciphers are disabled by default.
357 {
358 "RSA",
359 {
360 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
361 {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0},
362 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
363 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
364 },
365 false,
366 },
367 // But 3DES ciphers may be specified by name.
368 {
369 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
370 {
371 {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
372 },
373 false,
374 },
375 {
376 "DES-CBC3-SHA",
377 {
378 {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
379 },
380 false,
381 },
382 // Or by a selector that specifically includes deprecated ciphers.
383 {
384 "3DES",
385 {
386 {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
387 },
388 false,
389 },
390 // Such selectors may be combined with other selectors that would otherwise
391 // not allow deprecated ciphers.
392 {
393 "RSA+3DES",
394 {
395 {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
396 },
397 false,
398 },
399 // The cipher must still match all combined selectors, however. "ECDHE+3DES"
400 // matches nothing because we do not implement
401 // TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA. (The test includes
402 // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 so the final list is not empty.)
403 {
404 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:ECDHE+3DES",
405 {
406 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
407 },
408 false,
409 },
410 // Although alises like "RSA" do not match 3DES when adding ciphers, they do
411 // match it when removing ciphers.
412 {
413 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:RSA:RSA+3DES:!RSA",
414 {
415 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
416 },
417 false,
418 },
419 // 3DES still participates in strength sorting.
420 {
421 "RSA:3DES:@STRENGTH",
422 {
423 {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0},
424 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
425 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
426 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
427 {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
428 },
429 false,
430 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400431};
432
433static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400434 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400435 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
436 "RSA]",
437 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400438 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400439 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400440 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400441 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400442 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400443 "",
444 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400445 // COMPLEMENTOFDEFAULT is empty.
446 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400447 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448 "?BAR",
David Benjamin2da5ba92023-05-26 21:23:39 -0400449 // Special operators are not allowed if equi-preference groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400450 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
451 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
452 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
453 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700454 // Opcode supplied, but missing selector.
455 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700456 // Spaces are forbidden in equal-preference groups.
457 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400458};
459
Adam Langleyb1c6f452023-05-03 14:33:37 -0700460static const char *kMustNotIncludeDeprecated[] = {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700461 "ALL",
462 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500463 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700464 "FIPS",
465 "SHA",
466 "SHA1",
467 "RSA",
468 "SSLv3",
469 "TLSv1",
470 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700471};
472
Adam Langleyb1c6f452023-05-03 14:33:37 -0700473static const char* kShouldIncludeCBCSHA256[] = {
474 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
475 "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
476};
477
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100478static const CurveTest kCurveTests[] = {
479 {
480 "P-256",
David Benjamin335523a2023-05-26 21:55:56 -0400481 { SSL_GROUP_SECP256R1 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100482 },
483 {
David Benjamin1b724a62023-05-03 17:58:01 -0400484 "P-256:X25519Kyber768Draft00",
David Benjamin335523a2023-05-26 21:55:56 -0400485 { SSL_GROUP_SECP256R1, SSL_GROUP_X25519_KYBER768_DRAFT00 },
Adam Langley7b935932018-11-12 13:53:42 -0800486 },
487
488 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100489 "P-256:P-384:P-521:X25519",
490 {
David Benjamin335523a2023-05-26 21:55:56 -0400491 SSL_GROUP_SECP256R1,
492 SSL_GROUP_SECP384R1,
493 SSL_GROUP_SECP521R1,
494 SSL_GROUP_X25519,
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100495 },
496 },
David Benjamin6dda1662017-11-02 20:44:26 -0400497 {
498 "prime256v1:secp384r1:secp521r1:x25519",
499 {
David Benjamin335523a2023-05-26 21:55:56 -0400500 SSL_GROUP_SECP256R1,
501 SSL_GROUP_SECP384R1,
502 SSL_GROUP_SECP521R1,
503 SSL_GROUP_X25519,
David Benjamin6dda1662017-11-02 20:44:26 -0400504 },
505 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100506};
507
508static const char *kBadCurvesLists[] = {
509 "",
510 ":",
511 "::",
512 "P-256::X25519",
513 "RSA:P-256",
514 "P-256:RSA",
515 "X25519:P-256:",
516 ":X25519:P-256",
517};
518
David Benjamin70dbf042017-08-08 18:51:37 -0400519static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400520 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400521 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400522 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
523 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
524 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
525 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400526 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400527 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400528 }
David Benjamine11726a2017-04-23 12:14:28 -0400529 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400530 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400531 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400532 }
David Benjamine11726a2017-04-23 12:14:28 -0400533 ret += SSL_CIPHER_get_name(cipher);
534 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400535 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400536 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400537 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400538 }
539 }
David Benjamine11726a2017-04-23 12:14:28 -0400540 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400541}
542
David Benjamin70dbf042017-08-08 18:51:37 -0400543static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400544 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400545 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
546 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400547 return false;
David Benjamin65226252015-02-05 16:49:47 -0500548 }
549
David Benjamine11726a2017-04-23 12:14:28 -0400550 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400551 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400552 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400553 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400554 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400555 }
556 }
557
David Benjamin1d77e562015-03-22 17:22:08 -0400558 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400559}
560
Daniel McArdleff746c12019-09-16 12:35:05 -0400561TEST(GrowableArrayTest, Resize) {
562 GrowableArray<size_t> array;
563 ASSERT_TRUE(array.empty());
564 EXPECT_EQ(array.size(), 0u);
565
566 ASSERT_TRUE(array.Push(42));
567 ASSERT_TRUE(!array.empty());
568 EXPECT_EQ(array.size(), 1u);
569
570 // Force a resize operation to occur
571 for (size_t i = 0; i < 16; i++) {
572 ASSERT_TRUE(array.Push(i + 1));
573 }
574
575 EXPECT_EQ(array.size(), 17u);
576
577 // Verify that expected values are still contained in array
578 for (size_t i = 0; i < array.size(); i++) {
579 EXPECT_EQ(array[i], i == 0 ? 42 : i);
580 }
581}
582
583TEST(GrowableArrayTest, MoveConstructor) {
584 GrowableArray<size_t> array;
585 for (size_t i = 0; i < 100; i++) {
586 ASSERT_TRUE(array.Push(i));
587 }
588
589 GrowableArray<size_t> array_moved(std::move(array));
590 for (size_t i = 0; i < 100; i++) {
591 EXPECT_EQ(array_moved[i], i);
592 }
593}
594
595TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
596 // Representative example of a struct that contains a GrowableArray.
597 struct TagAndArray {
598 size_t tag;
599 GrowableArray<size_t> array;
600 };
601
602 GrowableArray<TagAndArray> array;
603 for (size_t i = 0; i < 100; i++) {
604 TagAndArray elem;
605 elem.tag = i;
606 for (size_t j = 0; j < i; j++) {
607 ASSERT_TRUE(elem.array.Push(j));
608 }
609 ASSERT_TRUE(array.Push(std::move(elem)));
610 }
611 EXPECT_EQ(array.size(), static_cast<size_t>(100));
612
613 GrowableArray<TagAndArray> array_moved(std::move(array));
614 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
615 size_t count = 0;
616 for (const TagAndArray &elem : array_moved) {
617 // Test the square bracket operator returns the same value as iteration.
618 EXPECT_EQ(&elem, &array_moved[count]);
619
620 EXPECT_EQ(elem.tag, count);
621 EXPECT_EQ(elem.array.size(), count);
622 for (size_t j = 0; j < count; j++) {
623 EXPECT_EQ(elem.array[j], j);
624 }
625 count++;
626 }
627}
628
David Benjamine11726a2017-04-23 12:14:28 -0400629TEST(SSLTest, CipherRules) {
630 for (const CipherTest &t : kCipherTests) {
631 SCOPED_TRACE(t.rule);
632 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
633 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700634
David Benjamine11726a2017-04-23 12:14:28 -0400635 // Test lax mode.
636 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400637 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400638 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400639 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400640
641 // Test strict mode.
642 if (t.strict_fail) {
643 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
644 } else {
645 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400646 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400647 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400648 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400649 }
650 }
651
David Benjaminfb974e62015-12-16 19:34:22 -0500652 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400653 SCOPED_TRACE(rule);
654 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
655 ASSERT_TRUE(ctx);
656
657 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400658 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400659 }
660
Adam Langleyb1c6f452023-05-03 14:33:37 -0700661 for (const char *rule : kMustNotIncludeDeprecated) {
David Benjamine11726a2017-04-23 12:14:28 -0400662 SCOPED_TRACE(rule);
663 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
664 ASSERT_TRUE(ctx);
665
666 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400667 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700668 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Adam Langleyb1c6f452023-05-03 14:33:37 -0700669 EXPECT_FALSE(ssl_cipher_is_deprecated(cipher));
670 }
671 }
672
673 {
674 for (const char *rule : kShouldIncludeCBCSHA256) {
675 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
676 ASSERT_TRUE(ctx);
677 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
678
679 bool found = false;
680 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
681 if ((TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff) ==
682 SSL_CIPHER_get_protocol_id(cipher)) {
683 found = true;
684 break;
685 }
686 }
687 EXPECT_TRUE(found);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700688 }
689 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400690}
David Benjamin2e521212014-07-16 14:37:51 -0400691
David Benjamine11726a2017-04-23 12:14:28 -0400692TEST(SSLTest, CurveRules) {
693 for (const CurveTest &t : kCurveTests) {
694 SCOPED_TRACE(t.rule);
695 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
696 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100697
David Benjamin2da5ba92023-05-26 21:23:39 -0400698 ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400699 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400700 for (size_t i = 0; i < t.expected.size(); i++) {
701 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100702 }
703 }
704
705 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400706 SCOPED_TRACE(rule);
707 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
708 ASSERT_TRUE(ctx);
709
David Benjamin2da5ba92023-05-26 21:23:39 -0400710 EXPECT_FALSE(SSL_CTX_set1_groups_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100711 ERR_clear_error();
712 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100713}
714
Adam Langley364f7a62016-12-12 10:51:00 -0800715// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700716static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800717 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700718 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
719 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
720 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
721 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
722 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
723 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
724 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
725 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
726 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
727 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
728 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
729 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
730 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
731 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
732 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
733 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
734 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
735 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
736 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
737 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
738 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
739 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
740 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
741 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
742 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
743 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
744 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
745 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
746 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800747 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700748
749// kCustomSession is a custom serialized SSL_SESSION generated by
750// filling in missing fields from |kOpenSSLSession|. This includes
751// providing |peer_sha256|, so |peer| is not serialized.
752static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400753 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700754 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400755 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
756 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
757 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
758 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
759 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
760 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700761
762// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
763static const char kBoringSSLSession[] =
764 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
765 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
766 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
767 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
768 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
769 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
770 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
771 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
772 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
773 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
774 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
775 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
776 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
777 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
778 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
779 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
780 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
781 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
782 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
783 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
784 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
785 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
786 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
787 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
788 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
789 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
790 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
791 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
792 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
793 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
794 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
795 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
796 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
797 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
798 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
799 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
800 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
801 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
802 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
803 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
804 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
805 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
806 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
807 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
808 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
809 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
810 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
811 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
812 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
813 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
814 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
815 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
816 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
817 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
818 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
819 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
820 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
821 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
822 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
823 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
824 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
825 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
826 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
827 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
828 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
829 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
830 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
831 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
832 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
833 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
834 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
835 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
836 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
837 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
838 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
839 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
840 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
841 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
842 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
843 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
844 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
845 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
846 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
847 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
848 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
849 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
850 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
851 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
852 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
853 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
854 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
855 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
856 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
857 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
858 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
859
860// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400861// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700862static const char kBadSessionExtraField[] =
863 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
864 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
865 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
866 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
867 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
868 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
869 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400870 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700871
872// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
873// the version of |kCustomSession| with 2.
874static const char kBadSessionVersion[] =
875 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
876 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
877 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
878 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
879 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
880 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
881 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
882 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
883
884// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
885// appended.
886static const char kBadSessionTrailingData[] =
887 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
888 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
889 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
890 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
891 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
892 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
893 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
894 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
895
David Benjamin1d77e562015-03-22 17:22:08 -0400896static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400897 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400898 if (!EVP_DecodedLength(&len, strlen(in))) {
899 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400900 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400901 }
902
David Benjamin1d77e562015-03-22 17:22:08 -0400903 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800904 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400905 strlen(in))) {
906 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400907 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400908 }
David Benjamin1d77e562015-03-22 17:22:08 -0400909 out->resize(len);
910 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400911}
912
David Benjamina486c6c2019-03-28 18:32:38 -0500913TEST(SSLTest, SessionEncoding) {
914 for (const char *input_b64 : {
915 kOpenSSLSession,
916 kCustomSession,
917 kBoringSSLSession,
918 }) {
919 SCOPED_TRACE(std::string(input_b64));
920 // Decode the input.
921 std::vector<uint8_t> input;
922 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400923
David Benjamina486c6c2019-03-28 18:32:38 -0500924 // Verify the SSL_SESSION decodes.
925 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
926 ASSERT_TRUE(ssl_ctx);
927 bssl::UniquePtr<SSL_SESSION> session(
928 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
929 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
930
931 // Verify the SSL_SESSION encoding round-trips.
932 size_t encoded_len;
933 bssl::UniquePtr<uint8_t> encoded;
934 uint8_t *encoded_raw;
935 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
936 << "SSL_SESSION_to_bytes failed";
937 encoded.reset(encoded_raw);
938 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
939 << "SSL_SESSION_to_bytes did not round-trip";
940
941 // Verify the SSL_SESSION also decodes with the legacy API.
942 const uint8_t *cptr = input.data();
943 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
944 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
945 EXPECT_EQ(cptr, input.data() + input.size());
946
947 // Verify the SSL_SESSION encoding round-trips via the legacy API.
948 int len = i2d_SSL_SESSION(session.get(), NULL);
949 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
950 ASSERT_EQ(static_cast<size_t>(len), input.size())
951 << "i2d_SSL_SESSION(NULL) returned invalid length";
952
953 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
954 ASSERT_TRUE(encoded);
955
956 uint8_t *ptr = encoded.get();
957 len = i2d_SSL_SESSION(session.get(), &ptr);
958 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
959 ASSERT_EQ(static_cast<size_t>(len), input.size())
960 << "i2d_SSL_SESSION(NULL) returned invalid length";
961 ASSERT_EQ(ptr, encoded.get() + input.size())
962 << "i2d_SSL_SESSION did not advance ptr correctly";
963 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
964 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400965 }
966
David Benjamina486c6c2019-03-28 18:32:38 -0500967 for (const char *input_b64 : {
968 kBadSessionExtraField,
969 kBadSessionVersion,
970 kBadSessionTrailingData,
971 }) {
972 SCOPED_TRACE(std::string(input_b64));
973 std::vector<uint8_t> input;
974 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400975
David Benjamina486c6c2019-03-28 18:32:38 -0500976 // Verify that the SSL_SESSION fails to decode.
977 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
978 ASSERT_TRUE(ssl_ctx);
979 bssl::UniquePtr<SSL_SESSION> session(
980 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
981 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
982 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400983 }
David Benjaminf297e022015-05-28 19:55:29 -0400984}
985
David Benjamin321fcdc2017-04-24 11:42:42 -0400986static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
987 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700988 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400989 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700990 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
991 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400992}
993
994TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800995 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400996 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
997 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
998 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700999 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
1000 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
1001 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -05001002}
1003
David Benjamin348f0d82017-08-10 16:06:27 -04001004TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -04001005 static const struct {
1006 int id;
1007 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -04001008 int cipher_nid;
1009 int digest_nid;
1010 int kx_nid;
1011 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -04001012 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -04001013 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -04001014 {
1015 SSL3_CK_RSA_DES_192_CBC3_SHA,
1016 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
1017 NID_des_ede3_cbc,
1018 NID_sha1,
1019 NID_kx_rsa,
1020 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001021 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001022 },
1023 {
1024 TLS1_CK_RSA_WITH_AES_128_SHA,
1025 "TLS_RSA_WITH_AES_128_CBC_SHA",
1026 NID_aes_128_cbc,
1027 NID_sha1,
1028 NID_kx_rsa,
1029 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001030 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001031 },
1032 {
1033 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
1034 "TLS_PSK_WITH_AES_256_CBC_SHA",
1035 NID_aes_256_cbc,
1036 NID_sha1,
1037 NID_kx_psk,
1038 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001039 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001040 },
1041 {
David Benjamin6e678ee2018-04-16 19:54:42 -04001042 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
1043 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -04001044 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -04001045 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001046 NID_kx_ecdhe,
1047 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -04001048 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001049 },
1050 {
David Benjamin6e678ee2018-04-16 19:54:42 -04001051 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1052 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -04001053 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -04001054 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001055 NID_kx_ecdhe,
1056 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -04001057 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001058 },
1059 {
1060 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1061 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
1062 NID_aes_128_gcm,
1063 NID_undef,
1064 NID_kx_ecdhe,
1065 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001066 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001067 },
1068 {
1069 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1070 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
1071 NID_aes_128_gcm,
1072 NID_undef,
1073 NID_kx_ecdhe,
1074 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001075 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001076 },
1077 {
1078 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
1079 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
1080 NID_aes_256_gcm,
1081 NID_undef,
1082 NID_kx_ecdhe,
1083 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001084 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001085 },
1086 {
1087 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
1088 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
1089 NID_aes_128_cbc,
1090 NID_sha1,
1091 NID_kx_ecdhe,
1092 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001093 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -04001094 },
1095 {
1096 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
1097 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
1098 NID_chacha20_poly1305,
1099 NID_undef,
1100 NID_kx_ecdhe,
1101 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001102 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001103 },
1104 {
David Benjamindfddbc42022-07-18 16:08:06 -04001105 TLS1_3_CK_AES_256_GCM_SHA384,
David Benjamin348f0d82017-08-10 16:06:27 -04001106 "TLS_AES_256_GCM_SHA384",
1107 NID_aes_256_gcm,
1108 NID_undef,
1109 NID_kx_any,
1110 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001111 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001112 },
1113 {
David Benjamindfddbc42022-07-18 16:08:06 -04001114 TLS1_3_CK_AES_128_GCM_SHA256,
David Benjamin348f0d82017-08-10 16:06:27 -04001115 "TLS_AES_128_GCM_SHA256",
1116 NID_aes_128_gcm,
1117 NID_undef,
1118 NID_kx_any,
1119 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001120 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001121 },
1122 {
David Benjamindfddbc42022-07-18 16:08:06 -04001123 TLS1_3_CK_CHACHA20_POLY1305_SHA256,
David Benjamin348f0d82017-08-10 16:06:27 -04001124 "TLS_CHACHA20_POLY1305_SHA256",
1125 NID_chacha20_poly1305,
1126 NID_undef,
1127 NID_kx_any,
1128 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001129 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001130 },
David Benjamin6fff3862017-06-21 21:07:04 -04001131 };
David Benjamin65226252015-02-05 16:49:47 -05001132
David Benjamin6fff3862017-06-21 21:07:04 -04001133 for (const auto &t : kTests) {
1134 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001135
1136 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1137 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001138 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1139
David Benjamin348f0d82017-08-10 16:06:27 -04001140 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1141 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1142 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1143 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjamin556a973f2023-06-03 23:32:27 -04001144 EXPECT_EQ(t.prf_nid, EVP_MD_nid(SSL_CIPHER_get_handshake_digest(cipher)));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001145 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001146 }
David Benjamin65226252015-02-05 16:49:47 -05001147}
1148
Steven Valdeza833c352016-11-01 13:39:36 -04001149// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1150// version and ticket length or nullptr on failure.
1151static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1152 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001153 std::vector<uint8_t> der;
1154 if (!DecodeBase64(&der, kOpenSSLSession)) {
1155 return nullptr;
1156 }
Adam Langley46db7af2017-02-01 15:49:37 -08001157
1158 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1159 if (!ssl_ctx) {
1160 return nullptr;
1161 }
David Benjaminaaef8332018-06-29 16:45:49 -04001162 // Use a garbage ticket.
1163 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001164 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001165 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001166 if (!session ||
1167 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1168 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001169 return nullptr;
1170 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001171 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001172#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001173 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001174#else
David Benjaminaaef8332018-06-29 16:45:49 -04001175 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001176#endif
David Benjamin422fe082015-07-21 22:03:43 -04001177 return session;
1178}
1179
David Benjaminafc64de2016-07-19 17:12:41 +02001180static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001181 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001182 if (!bio) {
1183 return false;
1184 }
1185 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001186 BIO_up_ref(bio.get());
1187 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001188 int ret = SSL_connect(ssl);
1189 if (ret > 0) {
1190 // SSL_connect should fail without a BIO to write to.
1191 return false;
1192 }
1193 ERR_clear_error();
1194
1195 const uint8_t *client_hello;
1196 size_t client_hello_len;
1197 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1198 return false;
1199 }
David Benjaminf7d37fb2023-02-04 19:45:04 -05001200
1201 // We did not get far enough to write a ClientHello.
1202 if (client_hello_len == 0) {
1203 return false;
1204 }
1205
David Benjaminafc64de2016-07-19 17:12:41 +02001206 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1207 return true;
1208}
1209
Steven Valdeza833c352016-11-01 13:39:36 -04001210// GetClientHelloLen creates a client SSL connection with the specified version
1211// and ticket length. It returns the length of the ClientHello, not including
1212// the record header, on success and zero on error.
1213static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1214 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001215 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001216 bssl::UniquePtr<SSL_SESSION> session =
1217 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001218 if (!ctx || !session) {
1219 return 0;
1220 }
Steven Valdeza833c352016-11-01 13:39:36 -04001221
1222 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001223 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001224 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001225 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001226 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001227 return 0;
1228 }
Steven Valdeza833c352016-11-01 13:39:36 -04001229
David Benjaminafc64de2016-07-19 17:12:41 +02001230 std::vector<uint8_t> client_hello;
1231 if (!GetClientHello(ssl.get(), &client_hello) ||
1232 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001233 return 0;
1234 }
Steven Valdeza833c352016-11-01 13:39:36 -04001235
David Benjaminafc64de2016-07-19 17:12:41 +02001236 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001237}
1238
David Benjamina486c6c2019-03-28 18:32:38 -05001239TEST(SSLTest, Padding) {
1240 struct PaddingVersions {
1241 uint16_t max_version, session_version;
1242 };
1243 static const PaddingVersions kPaddingVersions[] = {
1244 // Test the padding extension at TLS 1.2.
1245 {TLS1_2_VERSION, TLS1_2_VERSION},
1246 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1247 // will be no PSK binder after the padding extension.
1248 {TLS1_3_VERSION, TLS1_2_VERSION},
1249 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1250 // will be a PSK binder after the padding extension.
1251 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001252
David Benjamina486c6c2019-03-28 18:32:38 -05001253 };
David Benjamin422fe082015-07-21 22:03:43 -04001254
David Benjamina486c6c2019-03-28 18:32:38 -05001255 struct PaddingTest {
1256 size_t input_len, padded_len;
1257 };
1258 static const PaddingTest kPaddingTests[] = {
1259 // ClientHellos of length below 0x100 do not require padding.
1260 {0xfe, 0xfe},
1261 {0xff, 0xff},
1262 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1263 {0x100, 0x200},
1264 {0x123, 0x200},
1265 {0x1fb, 0x200},
1266 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1267 // padding extension takes a minimum of four bytes plus one required
1268 // content
1269 // byte. (To work around yet more server bugs, we avoid empty final
1270 // extensions.)
1271 {0x1fc, 0x201},
1272 {0x1fd, 0x202},
1273 {0x1fe, 0x203},
1274 {0x1ff, 0x204},
1275 // Finally, larger ClientHellos need no padding.
1276 {0x200, 0x200},
1277 {0x201, 0x201},
1278 };
David Benjamin422fe082015-07-21 22:03:43 -04001279
David Benjamina486c6c2019-03-28 18:32:38 -05001280 for (const PaddingVersions &versions : kPaddingVersions) {
1281 SCOPED_TRACE(versions.max_version);
1282 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001283
David Benjamina486c6c2019-03-28 18:32:38 -05001284 // Sample a baseline length.
1285 size_t base_len =
1286 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1287 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1288
1289 for (const PaddingTest &test : kPaddingTests) {
1290 SCOPED_TRACE(test.input_len);
1291 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1292
1293 size_t padded_len =
1294 GetClientHelloLen(versions.max_version, versions.session_version,
1295 1 + test.input_len - base_len);
1296 EXPECT_EQ(padded_len, test.padded_len)
1297 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001298 }
1299 }
David Benjamin422fe082015-07-21 22:03:43 -04001300}
1301
David Benjamin2f3958a2021-04-16 11:55:23 -04001302static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1303 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1304 if (!bio) {
1305 return nullptr;
1306 }
1307 return bssl::UniquePtr<X509>(
1308 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1309}
1310
1311static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1312 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1313 if (!bio) {
1314 return nullptr;
1315 }
1316 return bssl::UniquePtr<EVP_PKEY>(
1317 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1318}
1319
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001320static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001321 static const char kCertPEM[] =
1322 "-----BEGIN CERTIFICATE-----\n"
1323 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1324 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1325 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1326 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1327 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1328 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1329 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1330 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1331 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1332 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1333 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1334 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1335 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1336 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001337 return CertFromPEM(kCertPEM);
David Benjaminde942382016-02-11 12:02:01 -05001338}
1339
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001340static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001341 static const char kKeyPEM[] =
1342 "-----BEGIN RSA PRIVATE KEY-----\n"
1343 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1344 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1345 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1346 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1347 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1348 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1349 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1350 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1351 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1352 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1353 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1354 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1355 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1356 "-----END RSA PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001357 return KeyFromPEM(kKeyPEM);
David Benjaminde942382016-02-11 12:02:01 -05001358}
1359
David Benjamin9b2cdb72021-04-01 23:21:53 -04001360static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1361 const SSL_METHOD *method) {
1362 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1363 bssl::UniquePtr<X509> cert = GetTestCertificate();
1364 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1365 if (!ctx || !cert || !key ||
1366 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1367 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1368 return nullptr;
1369 }
1370 return ctx;
1371}
1372
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001373static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001374 static const char kCertPEM[] =
1375 "-----BEGIN CERTIFICATE-----\n"
1376 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1377 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1378 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1379 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1380 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1381 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1382 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1383 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1384 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1385 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1386 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001387 return CertFromPEM(kCertPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001388}
1389
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001390static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001391 static const char kKeyPEM[] =
1392 "-----BEGIN PRIVATE KEY-----\n"
1393 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1394 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1395 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1396 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001397 return KeyFromPEM(kKeyPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001398}
1399
Adam Langleyd04ca952017-02-28 11:26:51 -08001400static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1401 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1402 char *name, *header;
1403 uint8_t *data;
1404 long data_len;
1405 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1406 &data_len)) {
1407 return nullptr;
1408 }
1409 OPENSSL_free(name);
1410 OPENSSL_free(header);
1411
1412 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1413 CRYPTO_BUFFER_new(data, data_len, nullptr));
1414 OPENSSL_free(data);
1415 return ret;
1416}
1417
1418static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001419 static const char kCertPEM[] =
1420 "-----BEGIN CERTIFICATE-----\n"
1421 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1422 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1423 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1424 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1425 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1426 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1427 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1428 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1429 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1430 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1431 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1432 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1433 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1434 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1435 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1436 "1ngWZ7Ih\n"
1437 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001438 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001439}
1440
Adam Langleyd04ca952017-02-28 11:26:51 -08001441static bssl::UniquePtr<X509> X509FromBuffer(
1442 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1443 if (!buffer) {
1444 return nullptr;
1445 }
1446 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1447 return bssl::UniquePtr<X509>(
1448 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1449}
1450
1451static bssl::UniquePtr<X509> GetChainTestCertificate() {
1452 return X509FromBuffer(GetChainTestCertificateBuffer());
1453}
1454
1455static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001456 static const char kCertPEM[] =
1457 "-----BEGIN CERTIFICATE-----\n"
1458 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1459 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1460 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1461 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1462 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1463 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1464 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1465 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1466 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1467 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1468 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1469 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1470 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1471 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1472 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1473 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001474 return BufferFromPEM(kCertPEM);
1475}
1476
1477static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1478 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001479}
1480
1481static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1482 static const char kKeyPEM[] =
1483 "-----BEGIN PRIVATE KEY-----\n"
1484 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1485 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1486 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1487 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1488 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1489 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1490 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1491 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1492 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1493 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1494 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1495 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1496 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1497 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1498 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1499 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1500 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1501 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1502 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1503 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1504 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1505 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1506 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1507 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1508 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1509 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1510 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001511 return KeyFromPEM(kKeyPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001512}
1513
David Benjamin83a49932021-05-20 15:57:09 -04001514static bool CompleteHandshakes(SSL *client, SSL *server) {
1515 // Drive both their handshakes to completion.
1516 for (;;) {
1517 int client_ret = SSL_do_handshake(client);
1518 int client_err = SSL_get_error(client, client_ret);
1519 if (client_err != SSL_ERROR_NONE &&
1520 client_err != SSL_ERROR_WANT_READ &&
1521 client_err != SSL_ERROR_WANT_WRITE &&
1522 client_err != SSL_ERROR_PENDING_TICKET) {
1523 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
1524 return false;
1525 }
1526
1527 int server_ret = SSL_do_handshake(server);
1528 int server_err = SSL_get_error(server, server_ret);
1529 if (server_err != SSL_ERROR_NONE &&
1530 server_err != SSL_ERROR_WANT_READ &&
1531 server_err != SSL_ERROR_WANT_WRITE &&
1532 server_err != SSL_ERROR_PENDING_TICKET) {
1533 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
1534 return false;
1535 }
1536
1537 if (client_ret == 1 && server_ret == 1) {
1538 break;
1539 }
1540 }
1541
1542 return true;
1543}
1544
1545static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1546 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1547 // not pick them up until |SSL_read|.
1548 for (;;) {
1549 int server_ret = SSL_write(server, nullptr, 0);
1550 int server_err = SSL_get_error(server, server_ret);
1551 // The server may either succeed (|server_ret| is zero) or block on write
1552 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1553 if (server_ret > 0 ||
1554 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1555 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1556 server_err);
1557 return false;
1558 }
1559
1560 int client_ret = SSL_read(client, nullptr, 0);
1561 int client_err = SSL_get_error(client, client_ret);
1562 // The client must always block on read.
1563 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1564 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1565 client_err);
1566 return false;
1567 }
1568
1569 // The server flushed everything it had to write.
1570 if (server_ret == 0) {
1571 return true;
1572 }
1573 }
1574}
1575
1576// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1577// are paired with each other. It does not run the handshake. The caller is
1578// expected to configure the objects and drive the handshake as needed.
1579static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1580 bssl::UniquePtr<SSL> *out_server,
1581 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1582 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1583 if (!client || !server) {
1584 return false;
1585 }
1586 SSL_set_connect_state(client.get());
1587 SSL_set_accept_state(server.get());
1588
1589 BIO *bio1, *bio2;
1590 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1591 return false;
1592 }
1593 // SSL_set_bio takes ownership.
1594 SSL_set_bio(client.get(), bio1, bio1);
1595 SSL_set_bio(server.get(), bio2, bio2);
1596
1597 *out_client = std::move(client);
1598 *out_server = std::move(server);
1599 return true;
1600}
1601
1602struct ClientConfig {
1603 SSL_SESSION *session = nullptr;
1604 std::string servername;
Adam Langley7e7e6b62021-12-06 13:04:07 -08001605 std::string verify_hostname;
1606 unsigned hostflags = 0;
David Benjamin83a49932021-05-20 15:57:09 -04001607 bool early_data = false;
1608};
1609
1610static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1611 bssl::UniquePtr<SSL> *out_server,
1612 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1613 const ClientConfig &config = ClientConfig(),
1614 bool shed_handshake_config = true) {
1615 bssl::UniquePtr<SSL> client, server;
1616 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
1617 return false;
1618 }
1619 if (config.early_data) {
1620 SSL_set_early_data_enabled(client.get(), 1);
1621 }
1622 if (config.session) {
1623 SSL_set_session(client.get(), config.session);
1624 }
1625 if (!config.servername.empty() &&
1626 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1627 return false;
1628 }
Adam Langley7e7e6b62021-12-06 13:04:07 -08001629 if (!config.verify_hostname.empty()) {
1630 if (!SSL_set1_host(client.get(), config.verify_hostname.c_str())) {
1631 return false;
1632 }
1633 SSL_set_hostflags(client.get(), config.hostflags);
1634 }
David Benjamin83a49932021-05-20 15:57:09 -04001635
1636 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1637 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1638
1639 if (!CompleteHandshakes(client.get(), server.get())) {
1640 return false;
1641 }
1642
1643 *out_client = std::move(client);
1644 *out_server = std::move(server);
1645 return true;
1646}
1647
David Benjamin9734e442021-06-15 13:58:12 -04001648static bssl::UniquePtr<SSL_SESSION> g_last_session;
1649
1650static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1651 // Save the most recent session.
1652 g_last_session.reset(session);
1653 return 1;
1654}
1655
1656static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
1657 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1658 const ClientConfig &config = ClientConfig()) {
1659 g_last_session = nullptr;
1660 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1661
1662 // Connect client and server to get a session.
1663 bssl::UniquePtr<SSL> client, server;
1664 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1665 config) ||
1666 !FlushNewSessionTickets(client.get(), server.get())) {
1667 fprintf(stderr, "Failed to connect client and server.\n");
1668 return nullptr;
1669 }
1670
1671 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1672
1673 if (!g_last_session) {
1674 fprintf(stderr, "Client did not receive a session.\n");
1675 return nullptr;
1676 }
1677 return std::move(g_last_session);
1678}
1679
Victor Tan3309ca62023-09-29 01:57:01 +00001680static void SetUpExpectedNewCodePoint(SSL_CTX *ctx) {
1681 SSL_CTX_set_select_certificate_cb(
1682 ctx,
1683 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
1684 const uint8_t *data;
1685 size_t len;
1686 if (!SSL_early_callback_ctx_extension_get(
1687 client_hello, TLSEXT_TYPE_application_settings, &data,
1688 &len)) {
1689 ADD_FAILURE() << "Could not find alps new codepoint.";
1690 return ssl_select_cert_error;
1691 }
1692 return ssl_select_cert_success;
1693 });
1694}
1695
1696static void SetUpExpectedOldCodePoint(SSL_CTX *ctx) {
1697 SSL_CTX_set_select_certificate_cb(
1698 ctx,
1699 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
1700 const uint8_t *data;
1701 size_t len;
1702 if (!SSL_early_callback_ctx_extension_get(
1703 client_hello, TLSEXT_TYPE_application_settings_old, &data,
1704 &len)) {
1705 ADD_FAILURE() << "Could not find alps old codepoint.";
1706 return ssl_select_cert_error;
1707 }
1708 return ssl_select_cert_success;
1709 });
1710}
1711
David Benjaminc79ae7a2017-08-29 16:09:44 -04001712// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1713// before configuring as a server.
1714TEST(SSLTest, ClientCAList) {
1715 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1716 ASSERT_TRUE(ctx);
1717 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1718 ASSERT_TRUE(ssl);
1719
1720 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1721 ASSERT_TRUE(name);
1722
1723 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1724 ASSERT_TRUE(name_dup);
1725
1726 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1727 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001728 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001729
1730 // |SSL_set_client_CA_list| takes ownership.
1731 SSL_set_client_CA_list(ssl.get(), stack.release());
1732
1733 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1734 ASSERT_TRUE(result);
1735 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1736 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1737}
1738
1739TEST(SSLTest, AddClientCA) {
1740 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1741 ASSERT_TRUE(ctx);
1742 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1743 ASSERT_TRUE(ssl);
1744
1745 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1746 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1747 ASSERT_TRUE(cert1 && cert2);
1748 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1749 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1750
1751 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1752
1753 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1754 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1755
1756 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1757 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1758 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1759 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1760
1761 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1762
1763 list = SSL_get_client_CA_list(ssl.get());
1764 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1765 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1766 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1767 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1768}
1769
David Benjamin24545c52021-06-07 16:05:07 -04001770struct ECHConfigParams {
1771 uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1772 uint16_t config_id = 1;
1773 std::string public_name = "example.com";
1774 const EVP_HPKE_KEY *key = nullptr;
1775 // kem_id, if zero, takes its value from |key|.
1776 uint16_t kem_id = 0;
1777 // public_key, if empty takes its value from |key|.
1778 std::vector<uint8_t> public_key;
1779 size_t max_name_len = 16;
1780 // cipher_suites is a list of code points which should contain pairs of KDF
1781 // and AEAD IDs.
1782 std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1783 EVP_HPKE_AES_128_GCM};
1784 std::vector<uint8_t> extensions;
1785};
Daniel McArdle00e434d2021-02-18 11:47:18 -05001786
David Benjamin24545c52021-06-07 16:05:07 -04001787// MakeECHConfig serializes an ECHConfig from |params| and writes it to
1788// |*out|.
1789bool MakeECHConfig(std::vector<uint8_t> *out,
1790 const ECHConfigParams &params) {
1791 uint16_t kem_id = params.kem_id == 0
1792 ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1793 : params.kem_id;
1794 std::vector<uint8_t> public_key = params.public_key;
1795 if (public_key.empty()) {
1796 public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1797 size_t len;
1798 if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1799 public_key.size())) {
1800 return false;
1801 }
1802 public_key.resize(len);
1803 }
Daniel McArdle00e434d2021-02-18 11:47:18 -05001804
Daniel McArdle00e434d2021-02-18 11:47:18 -05001805 bssl::ScopedCBB cbb;
1806 CBB contents, child;
Daniel McArdle00e434d2021-02-18 11:47:18 -05001807 if (!CBB_init(cbb.get(), 64) ||
David Benjamin24545c52021-06-07 16:05:07 -04001808 !CBB_add_u16(cbb.get(), params.version) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001809 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
David Benjamin24545c52021-06-07 16:05:07 -04001810 !CBB_add_u8(&contents, params.config_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001811 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001812 !CBB_add_u16_length_prefixed(&contents, &child) ||
1813 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001814 !CBB_add_u16_length_prefixed(&contents, &child)) {
1815 return false;
1816 }
David Benjamin24545c52021-06-07 16:05:07 -04001817 for (uint16_t cipher_suite : params.cipher_suites) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001818 if (!CBB_add_u16(&child, cipher_suite)) {
1819 return false;
1820 }
1821 }
David Benjamin18b68362021-06-18 23:13:46 -04001822 if (!CBB_add_u8(&contents, params.max_name_len) ||
1823 !CBB_add_u8_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001824 !CBB_add_bytes(
1825 &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1826 params.public_name.size()) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001827 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001828 !CBB_add_bytes(&child, params.extensions.data(),
1829 params.extensions.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001830 !CBB_flush(cbb.get())) {
1831 return false;
1832 }
1833
1834 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1835 return true;
1836}
1837
David Benjaminba423c92021-06-15 16:26:58 -04001838static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys(uint8_t config_id = 1) {
David Benjamin83a49932021-05-20 15:57:09 -04001839 bssl::ScopedEVP_HPKE_KEY key;
1840 uint8_t *ech_config;
1841 size_t ech_config_len;
1842 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
David Benjaminba423c92021-06-15 16:26:58 -04001843 !SSL_marshal_ech_config(&ech_config, &ech_config_len, config_id,
1844 key.get(), "public.example", 16)) {
David Benjamin83a49932021-05-20 15:57:09 -04001845 return nullptr;
1846 }
1847 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1848
1849 // Install a non-retry config.
1850 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1851 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1852 ech_config_len, key.get())) {
1853 return nullptr;
1854 }
1855 return keys;
1856}
1857
1858static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1859 uint8_t *ech_config_list;
1860 size_t ech_config_list_len;
1861 if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1862 &ech_config_list_len)) {
1863 return false;
1864 }
1865 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1866 return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1867}
1868
David Benjamin24545c52021-06-07 16:05:07 -04001869// Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1870// output values as expected.
1871TEST(SSLTest, MarshalECHConfig) {
1872 static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1873 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1874 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1875 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1876 bssl::ScopedEVP_HPKE_KEY key;
1877 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1878 kPrivateKey, sizeof(kPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001879
David Benjamin24545c52021-06-07 16:05:07 -04001880 static const uint8_t kECHConfig[] = {
1881 // version
David Benjamin18b68362021-06-18 23:13:46 -04001882 0xfe, 0x0d,
David Benjamin24545c52021-06-07 16:05:07 -04001883 // length
David Benjamin18b68362021-06-18 23:13:46 -04001884 0x00, 0x41,
David Benjamin24545c52021-06-07 16:05:07 -04001885 // contents.config_id
1886 0x01,
1887 // contents.kem_id
1888 0x00, 0x20,
1889 // contents.public_key
1890 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1891 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1892 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1893 // contents.cipher_suites
1894 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1895 // contents.maximum_name_length
David Benjamin18b68362021-06-18 23:13:46 -04001896 0x10,
David Benjamin24545c52021-06-07 16:05:07 -04001897 // contents.public_name
David Benjamin18b68362021-06-18 23:13:46 -04001898 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
1899 0x70, 0x6c, 0x65,
David Benjamin24545c52021-06-07 16:05:07 -04001900 // contents.extensions
1901 0x00, 0x00};
1902 uint8_t *ech_config;
1903 size_t ech_config_len;
1904 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1905 /*config_id=*/1, key.get(),
1906 "public.example", 16));
1907 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1908 EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1909
1910 // Generate a second ECHConfig.
1911 bssl::ScopedEVP_HPKE_KEY key2;
1912 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1913 uint8_t *ech_config2;
1914 size_t ech_config2_len;
1915 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1916 /*config_id=*/2, key2.get(),
1917 "public.example", 16));
1918 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1919
1920 // Install both ECHConfigs in an |SSL_ECH_KEYS|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001921 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1922 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001923 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1924 ech_config_len, key.get()));
1925 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1926 ech_config2_len, key2.get()));
1927
1928 // The ECHConfigList should be correctly serialized.
1929 uint8_t *ech_config_list;
1930 size_t ech_config_list_len;
1931 ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1932 &ech_config_list_len));
1933 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1934
1935 // ECHConfigList is just the concatenation with a length prefix.
1936 size_t len = ech_config_len + ech_config2_len;
1937 std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1938 expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1939 expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1940 EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
David Benjamin24545c52021-06-07 16:05:07 -04001941}
1942
1943TEST(SSLTest, ECHHasDuplicateConfigID) {
1944 const struct {
1945 std::vector<uint8_t> ids;
1946 bool has_duplicate;
1947 } kTests[] = {
1948 {{}, false},
1949 {{1}, false},
1950 {{1, 2, 3, 255}, false},
1951 {{1, 2, 3, 1}, true},
1952 };
1953 for (const auto &test : kTests) {
1954 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1955 ASSERT_TRUE(keys);
1956 for (const uint8_t id : test.ids) {
1957 bssl::ScopedEVP_HPKE_KEY key;
1958 ASSERT_TRUE(
1959 EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1960 uint8_t *ech_config;
1961 size_t ech_config_len;
1962 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
1963 key.get(), "public.example", 16));
1964 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1965 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1966 ech_config, ech_config_len, key.get()));
1967 }
1968
1969 EXPECT_EQ(test.has_duplicate ? 1 : 0,
1970 SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
1971 }
1972}
1973
1974// Test that |SSL_ECH_KEYS_add| checks consistency between the public and
1975// private key.
1976TEST(SSLTest, ECHKeyConsistency) {
1977 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1978 ASSERT_TRUE(keys);
1979 bssl::ScopedEVP_HPKE_KEY key;
1980 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1981 uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
1982 size_t public_key_len;
1983 ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
1984 sizeof(public_key)));
1985
1986 // Adding an ECHConfig with the matching public key succeeds.
1987 ECHConfigParams params;
1988 params.key = key.get();
1989 std::vector<uint8_t> ech_config;
1990 ASSERT_TRUE(MakeECHConfig(&ech_config, params));
1991 EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1992 ech_config.data(), ech_config.size(),
1993 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001994
David Benjaminc890ae52021-06-06 13:32:29 -04001995 // Adding an ECHConfig with the wrong public key is an error.
1996 bssl::ScopedEVP_HPKE_KEY wrong_key;
1997 ASSERT_TRUE(
1998 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjamin24545c52021-06-07 16:05:07 -04001999 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2000 ech_config.data(), ech_config.size(),
2001 wrong_key.get()));
2002
2003 // Adding an ECHConfig with a truncated public key is an error.
2004 ECHConfigParams truncated;
2005 truncated.key = key.get();
2006 truncated.public_key.assign(public_key, public_key + public_key_len - 1);
2007 ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
2008 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2009 ech_config.data(), ech_config.size(), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002010
David Benjaminc890ae52021-06-06 13:32:29 -04002011 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
2012 // error.
David Benjamin24545c52021-06-07 16:05:07 -04002013 ECHConfigParams wrong_kem;
2014 wrong_kem.key = key.get();
2015 wrong_kem.kem_id = 0x0010; // DHKEM(P-256, HKDF-SHA256)
2016 ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
David Benjaminc890ae52021-06-06 13:32:29 -04002017 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2018 ech_config.data(), ech_config.size(),
2019 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002020}
2021
David Benjaminc3b373b2021-06-06 13:04:26 -04002022// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05002023// has no retry configs.
2024TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
David Benjamin24545c52021-06-07 16:05:07 -04002025 bssl::ScopedEVP_HPKE_KEY key;
2026 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
2027 uint8_t *ech_config;
2028 size_t ech_config_len;
2029 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
2030 /*config_id=*/1, key.get(),
2031 "public.example", 16));
2032 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
Daniel McArdle00e434d2021-02-18 11:47:18 -05002033
David Benjamin24545c52021-06-07 16:05:07 -04002034 // Install a non-retry config.
David Benjaminc3b373b2021-06-06 13:04:26 -04002035 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2036 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04002037 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
2038 ech_config_len, key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002039
David Benjamin24545c52021-06-07 16:05:07 -04002040 // |keys| has no retry configs.
2041 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2042 ASSERT_TRUE(ctx);
2043 EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002044
2045 // Add the same ECHConfig to the list, but this time mark it as a retry
2046 // config.
David Benjamin24545c52021-06-07 16:05:07 -04002047 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2048 ech_config_len, key.get()));
2049 EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002050}
2051
2052// Test that the server APIs reject ECHConfigs with unsupported features.
2053TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04002054 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2055 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04002056 bssl::ScopedEVP_HPKE_KEY key;
David Benjamin24545c52021-06-07 16:05:07 -04002057 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002058
2059 // Unsupported versions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04002060 ECHConfigParams unsupported_version;
2061 unsupported_version.version = 0xffff;
2062 unsupported_version.key = key.get();
Daniel McArdle00e434d2021-02-18 11:47:18 -05002063 std::vector<uint8_t> ech_config;
David Benjamin24545c52021-06-07 16:05:07 -04002064 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
David Benjaminc3b373b2021-06-06 13:04:26 -04002065 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2066 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04002067 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002068
David Benjamin24545c52021-06-07 16:05:07 -04002069 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
2070 ECHConfigParams unsupported_kdf;
2071 unsupported_kdf.key = key.get();
2072 unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
2073 EVP_HPKE_AES_128_GCM};
2074 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
2075 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2076 ech_config.data(), ech_config.size(),
2077 key.get()));
2078 ECHConfigParams unsupported_aead;
2079 unsupported_aead.key = key.get();
2080 unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
2081 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
2082 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2083 ech_config.data(), ech_config.size(),
2084 key.get()));
2085
2086
Daniel McArdle00e434d2021-02-18 11:47:18 -05002087 // Unsupported extensions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04002088 ECHConfigParams extensions;
2089 extensions.key = key.get();
2090 extensions.extensions = {0x00, 0x01, 0x00, 0x00};
2091 ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04002092 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2093 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04002094 key.get()));
David Benjamin9cbe7372021-06-15 18:09:10 -04002095
2096 // Invalid public names are rejected.
2097 ECHConfigParams invalid_public_name;
2098 invalid_public_name.key = key.get();
2099 invalid_public_name.public_name = "dns_names_have_no_underscores.example";
2100 ASSERT_TRUE(MakeECHConfig(&ech_config, invalid_public_name));
2101 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2102 ech_config.data(), ech_config.size(),
2103 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05002104}
2105
David Benjamin83a49932021-05-20 15:57:09 -04002106// Test that |SSL_get_client_random| reports the correct value on both client
2107// and server in ECH. The client sends two different random values. When ECH is
2108// accepted, we should report the inner one.
2109TEST(SSLTest, ECHClientRandomsMatch) {
2110 bssl::UniquePtr<SSL_CTX> server_ctx =
2111 CreateContextWithTestCertificate(TLS_method());
David Benjaminf7d37fb2023-02-04 19:45:04 -05002112 ASSERT_TRUE(server_ctx);
David Benjamin83a49932021-05-20 15:57:09 -04002113 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
2114 ASSERT_TRUE(keys);
2115 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
2116
2117 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2118 ASSERT_TRUE(client_ctx);
2119 bssl::UniquePtr<SSL> client, server;
2120 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2121 server_ctx.get()));
2122 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
2123 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2124
2125 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2126 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2127
2128 // An ECH server will fairly naturally record the inner ClientHello random,
2129 // but an ECH client may forget to update the random once ClientHelloInner is
2130 // selected.
2131 uint8_t client_random1[SSL3_RANDOM_SIZE];
2132 uint8_t client_random2[SSL3_RANDOM_SIZE];
2133 ASSERT_EQ(sizeof(client_random1),
2134 SSL_get_client_random(client.get(), client_random1,
2135 sizeof(client_random1)));
2136 ASSERT_EQ(sizeof(client_random2),
2137 SSL_get_client_random(server.get(), client_random2,
2138 sizeof(client_random2)));
2139 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
2140}
2141
2142// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
2143// of the ClientHello and ECH extension, respectively, when a client created
2144// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
2145// maximum name length |max_name_len|.
2146static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
2147 size_t *out_ech_len, size_t max_name_len,
2148 const char *name) {
2149 bssl::ScopedEVP_HPKE_KEY key;
2150 uint8_t *ech_config;
2151 size_t ech_config_len;
2152 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
2153 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
2154 /*config_id=*/1, key.get(), "public.example",
2155 max_name_len)) {
2156 return false;
2157 }
2158 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2159
2160 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2161 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2162 ech_config_len, key.get())) {
2163 return false;
2164 }
2165
2166 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
2167 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
2168 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
2169 return false;
2170 }
2171 SSL_set_connect_state(ssl.get());
2172
2173 std::vector<uint8_t> client_hello;
2174 SSL_CLIENT_HELLO parsed;
2175 const uint8_t *unused;
2176 if (!GetClientHello(ssl.get(), &client_hello) ||
2177 !ssl_client_hello_init(
2178 ssl.get(), &parsed,
2179 // Skip record and handshake headers. This assumes the ClientHello
2180 // fits in one record.
2181 MakeConstSpan(client_hello)
2182 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
2183 !SSL_early_callback_ctx_extension_get(
2184 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2185 return false;
2186 }
2187 *out_client_hello_len = client_hello.size();
2188 return true;
2189}
2190
2191TEST(SSLTest, ECHPadding) {
2192 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2193 ASSERT_TRUE(ctx);
2194
2195 // Sample lengths with max_name_len = 128 as baseline.
2196 size_t client_hello_len_baseline, ech_len_baseline;
2197 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2198 &ech_len_baseline, 128, "example.com"));
2199
2200 // Check that all name lengths under the server's maximum look the same.
2201 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2202 SCOPED_TRACE(name_len);
2203 size_t client_hello_len, ech_len;
2204 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2205 std::string(name_len, 'a').c_str()));
2206 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2207 EXPECT_EQ(ech_len, ech_len_baseline);
2208 }
2209
2210 // When sending no SNI, we must still pad as if we are sending one.
2211 size_t client_hello_len, ech_len;
2212 ASSERT_TRUE(
2213 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2214 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2215 EXPECT_EQ(ech_len, ech_len_baseline);
2216
David Benjamin18b68362021-06-18 23:13:46 -04002217 // Name lengths above the maximum do not get named-based padding, but the
2218 // overall input is padded to a multiple of 32.
2219 size_t client_hello_len_baseline2, ech_len_baseline2;
2220 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline2,
2221 &ech_len_baseline2, 128,
2222 std::string(128 + 32, 'a').c_str()));
2223 EXPECT_EQ(ech_len_baseline2, ech_len_baseline + 32);
2224 // The ClientHello lengths may match if we are still under the threshold for
2225 // padding extension.
2226 EXPECT_GE(client_hello_len_baseline2, client_hello_len_baseline);
David Benjamin83a49932021-05-20 15:57:09 -04002227
David Benjamin18b68362021-06-18 23:13:46 -04002228 for (size_t name_len = 128 + 1; name_len < 128 + 32; name_len++) {
David Benjamin83a49932021-05-20 15:57:09 -04002229 SCOPED_TRACE(name_len);
2230 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2231 std::string(name_len, 'a').c_str()));
David Benjamin18b68362021-06-18 23:13:46 -04002232 EXPECT_TRUE(ech_len == ech_len_baseline || ech_len == ech_len_baseline2)
2233 << ech_len;
2234 EXPECT_TRUE(client_hello_len == client_hello_len_baseline ||
2235 client_hello_len == client_hello_len_baseline2)
2236 << client_hello_len;
David Benjamin83a49932021-05-20 15:57:09 -04002237 }
2238}
2239
David Benjamin9cbe7372021-06-15 18:09:10 -04002240TEST(SSLTest, ECHPublicName) {
2241 auto str_to_span = [](const char *str) -> Span<const uint8_t> {
2242 return MakeConstSpan(reinterpret_cast<const uint8_t *>(str), strlen(str));
2243 };
2244
2245 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("")));
2246 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("example.com")));
2247 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(".example.com")));
2248 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.com.")));
2249 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example..com")));
2250 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.-example.com")));
2251 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.example-.com")));
2252 EXPECT_FALSE(
2253 ssl_is_valid_ech_public_name(str_to_span("no_underscores.example")));
2254 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2255 str_to_span("invalid_chars.\x01.example")));
2256 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2257 str_to_span("invalid_chars.\xff.example")));
2258 static const uint8_t kWithNUL[] = {'t', 'e', 's', 't', 0};
2259 EXPECT_FALSE(ssl_is_valid_ech_public_name(kWithNUL));
2260
2261 // Test an LDH label with every character and the maximum length.
2262 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span(
2263 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789")));
2264 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(
2265 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-01234567899")));
2266
David Benjamin1a668b32021-09-02 23:00:28 -04002267 // Inputs with trailing numeric components are rejected.
David Benjamin9cbe7372021-06-15 18:09:10 -04002268 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.0.0.1")));
David Benjamin1a668b32021-09-02 23:00:28 -04002269 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.1")));
2270 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.01")));
2271 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0x01")));
2272 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0X01")));
2273 // Leading zeros and values that overflow |uint32_t| are still rejected.
2274 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2275 str_to_span("example.123456789000000000000000")));
2276 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2277 str_to_span("example.012345678900000000000000")));
2278 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2279 str_to_span("example.0x123456789abcdefABCDEF0")));
2280 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2281 str_to_span("example.0x0123456789abcdefABCDEF")));
2282 // Adding a non-digit or non-hex character makes it a valid DNS name again.
2283 // Single-component numbers are rejected.
David Benjamin9cbe7372021-06-15 18:09:10 -04002284 EXPECT_TRUE(ssl_is_valid_ech_public_name(
David Benjamin1a668b32021-09-02 23:00:28 -04002285 str_to_span("example.1234567890a")));
2286 EXPECT_TRUE(ssl_is_valid_ech_public_name(
2287 str_to_span("example.01234567890a")));
2288 EXPECT_TRUE(ssl_is_valid_ech_public_name(
2289 str_to_span("example.0x123456789abcdefg")));
2290 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1")));
2291 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01")));
2292 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01")));
2293 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01")));
2294 // Numbers with trailing dots are rejected. (They are already rejected by the
2295 // LDH label rules, but the WHATWG URL parser additionally rejects them.)
2296 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1.")));
2297 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01.")));
2298 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01.")));
2299 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01.")));
David Benjamin9cbe7372021-06-15 18:09:10 -04002300}
2301
David Benjaminba423c92021-06-15 16:26:58 -04002302// When using the built-in verifier, test that |SSL_get0_ech_name_override| is
2303// applied automatically.
2304TEST(SSLTest, ECHBuiltinVerifier) {
2305 // These test certificates generated with the following Go program.
2306 /* clang-format off
2307func main() {
2308 notBefore := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
2309 notAfter := time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC)
2310 rootKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2311 rootTemplate := &x509.Certificate{
2312 SerialNumber: big.NewInt(1),
2313 Subject: pkix.Name{CommonName: "Test CA"},
2314 NotBefore: notBefore,
2315 NotAfter: notAfter,
2316 BasicConstraintsValid: true,
2317 IsCA: true,
2318 }
2319 rootDER, _ := x509.CreateCertificate(rand.Reader, rootTemplate, rootTemplate, &rootKey.PublicKey, rootKey)
2320 root, _ := x509.ParseCertificate(rootDER)
2321 pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: rootDER})
2322 leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2323 leafKeyDER, _ := x509.MarshalPKCS8PrivateKey(leafKey)
2324 pem.Encode(os.Stdout, &pem.Block{Type: "PRIVATE KEY", Bytes: leafKeyDER})
2325 for i, name := range []string{"public.example", "secret.example"} {
2326 leafTemplate := &x509.Certificate{
2327 SerialNumber: big.NewInt(int64(i) + 2),
2328 Subject: pkix.Name{CommonName: name},
2329 NotBefore: notBefore,
2330 NotAfter: notAfter,
2331 BasicConstraintsValid: true,
2332 DNSNames: []string{name},
2333 }
2334 leafDER, _ := x509.CreateCertificate(rand.Reader, leafTemplate, root, &leafKey.PublicKey, rootKey)
2335 pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
2336 }
2337}
2338clang-format on */
2339 bssl::UniquePtr<X509> root = CertFromPEM(R"(
2340-----BEGIN CERTIFICATE-----
2341MIIBRzCB7aADAgECAgEBMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMTB1Rlc3QgQ0Ew
2342IBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMBIxEDAOBgNVBAMTB1Rl
2343c3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT5JUjrI1DAxSpEl88UkmJw
2344tAJqxo/YrSFo9V3MkcNkfTixi5p6MUtO8DazhEgekBcd2+tBAWtl7dy0qpvTqx92
2345ozIwMDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTw6ftkexAI6o4r5FntJIfL
2346GU5F4zAKBggqhkjOPQQDAgNJADBGAiEAiiNowddQeHZaZFIygwe6RW5/WG4sUXWC
2347dkyl9CQzRaYCIQCFS1EvwZbZtMny27fYm1eeYciY0TkJTEi34H1KwyzzIA==
2348-----END CERTIFICATE-----
2349)");
2350 ASSERT_TRUE(root);
2351 bssl::UniquePtr<EVP_PKEY> leaf_key = KeyFromPEM(R"(
2352-----BEGIN PRIVATE KEY-----
2353MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgj5WKHwHnziiyPauf
23547QukxTwtTyGZkk8qNdms4puJfxqhRANCAARNrkhxabALDlJrHtvkuDwvCWUF/oVC
2355hr6PDITHi1lDlJzvVT4aXBH87sH2n2UV5zpx13NHkq1bIC8eRT8eOIe0
2356-----END PRIVATE KEY-----
2357)");
2358 ASSERT_TRUE(leaf_key);
2359 bssl::UniquePtr<X509> leaf_public = CertFromPEM(R"(
2360-----BEGIN CERTIFICATE-----
2361MIIBaDCCAQ6gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2362MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5w
2363dWJsaWMuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2364Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2365Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2366K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOcHVibGljLmV4YW1wbGUwCgYIKoZIzj0E
2367AwIDSAAwRQIhANqZRhDR/+QL05hsWXMYEwaiHifd9iakKoFEhKFchcF3AiBRAeXw
2368wRGGT6+iPmTYM6N5/IDyAb5B9Ke38O6lLEsUwA==
2369-----END CERTIFICATE-----
2370)");
2371 ASSERT_TRUE(leaf_public);
2372 bssl::UniquePtr<X509> leaf_secret = CertFromPEM(R"(
2373-----BEGIN CERTIFICATE-----
2374MIIBaTCCAQ6gAwIBAgIBAzAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2375MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5z
2376ZWNyZXQuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2377Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2378Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2379K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOc2VjcmV0LmV4YW1wbGUwCgYIKoZIzj0E
2380AwIDSQAwRgIhAPQdIz1xCFkc9WuSkxOxJDpywZiEp9SnKcxJ9nwrlRp3AiEA+O3+
2381XRqE7XFhHL+7TNC2a9OOAjQsEF137YPWo+rhgko=
2382-----END CERTIFICATE-----
2383)");
2384 ASSERT_TRUE(leaf_secret);
2385
2386 // Use different config IDs so that fuzzer mode, which breaks trial
2387 // decryption, will observe the key mismatch.
2388 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys(/*config_id=*/1);
2389 ASSERT_TRUE(keys);
2390 bssl::UniquePtr<SSL_ECH_KEYS> wrong_keys = MakeTestECHKeys(/*config_id=*/2);
2391 ASSERT_TRUE(wrong_keys);
2392 bssl::UniquePtr<SSL_CTX> server_ctx =
2393 CreateContextWithTestCertificate(TLS_method());
2394 ASSERT_TRUE(server_ctx);
2395 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2396 ASSERT_TRUE(client_ctx);
2397
2398 // Configure the client to verify certificates and expect the secret name.
2399 // This is the name the client is trying to connect to. If ECH is rejected,
2400 // BoringSSL will internally override this setting with the public name.
2401 bssl::UniquePtr<X509_STORE> store(X509_STORE_new());
2402 ASSERT_TRUE(store);
2403 ASSERT_TRUE(X509_STORE_add_cert(store.get(), root.get()));
2404 SSL_CTX_set_cert_store(client_ctx.get(), store.release());
2405 SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER, nullptr);
David Benjaminc7b255e2022-12-07 12:50:04 -05002406 X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
2407 X509_V_FLAG_NO_CHECK_TIME);
David Benjaminba423c92021-06-15 16:26:58 -04002408 static const char kSecretName[] = "secret.example";
2409 ASSERT_TRUE(X509_VERIFY_PARAM_set1_host(SSL_CTX_get0_param(client_ctx.get()),
2410 kSecretName, strlen(kSecretName)));
2411
2412 // For simplicity, we only run through a pair of representative scenarios here
2413 // and rely on runner.go to verify that |SSL_get0_ech_name_override| behaves
2414 // correctly.
2415 for (bool accept_ech : {false, true}) {
2416 SCOPED_TRACE(accept_ech);
2417 for (bool use_leaf_secret : {false, true}) {
2418 SCOPED_TRACE(use_leaf_secret);
2419
2420 // The server will reject ECH when configured with the wrong keys.
2421 ASSERT_TRUE(SSL_CTX_set1_ech_keys(
2422 server_ctx.get(), accept_ech ? keys.get() : wrong_keys.get()));
2423
2424 bssl::UniquePtr<SSL> client, server;
2425 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2426 server_ctx.get()));
2427 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
2428
2429 // Configure the server with the selected certificate.
2430 ASSERT_TRUE(SSL_use_certificate(server.get(), use_leaf_secret
2431 ? leaf_secret.get()
2432 : leaf_public.get()));
2433 ASSERT_TRUE(SSL_use_PrivateKey(server.get(), leaf_key.get()));
2434
2435 // The handshake may fail due to name mismatch or ECH reject. We check
2436 // |SSL_get_verify_result| to confirm the handshake got far enough.
2437 CompleteHandshakes(client.get(), server.get());
2438 EXPECT_EQ(accept_ech == use_leaf_secret ? X509_V_OK
2439 : X509_V_ERR_HOSTNAME_MISMATCH,
2440 SSL_get_verify_result(client.get()));
2441 }
2442 }
2443}
2444
David Benjamin83a49932021-05-20 15:57:09 -04002445#if defined(OPENSSL_THREADS)
2446// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2447// in use on other threads. This test is intended to be run with TSan.
2448TEST(SSLTest, ECHThreads) {
2449 // Generate a pair of ECHConfigs.
2450 bssl::ScopedEVP_HPKE_KEY key1;
2451 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2452 uint8_t *ech_config1;
2453 size_t ech_config1_len;
2454 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2455 /*config_id=*/1, key1.get(),
2456 "public.example", 16));
2457 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2458 bssl::ScopedEVP_HPKE_KEY key2;
2459 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2460 uint8_t *ech_config2;
2461 size_t ech_config2_len;
2462 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2463 /*config_id=*/2, key2.get(),
2464 "public.example", 16));
2465 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2466
2467 // |keys1| contains the first config. |keys12| contains both.
2468 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2469 ASSERT_TRUE(keys1);
2470 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2471 ech_config1_len, key1.get()));
2472 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2473 ASSERT_TRUE(keys12);
2474 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2475 ech_config2_len, key2.get()));
2476 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2477 ech_config1_len, key1.get()));
2478
2479 bssl::UniquePtr<SSL_CTX> server_ctx =
2480 CreateContextWithTestCertificate(TLS_method());
David Benjaminf7d37fb2023-02-04 19:45:04 -05002481 ASSERT_TRUE(server_ctx);
David Benjamin83a49932021-05-20 15:57:09 -04002482 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2483
2484 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2485 ASSERT_TRUE(client_ctx);
2486 bssl::UniquePtr<SSL> client, server;
2487 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2488 server_ctx.get()));
2489 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2490
2491 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2492 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2493 // the same whichever the server uses.
2494 std::vector<std::thread> threads;
2495 threads.emplace_back([&] {
2496 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2497 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2498 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2499 });
2500 threads.emplace_back([&] {
2501 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2502 });
2503 for (auto &thread : threads) {
2504 thread.join();
2505 }
2506}
2507#endif // OPENSSL_THREADS
2508
Nick Harper10458972022-10-26 15:28:08 -04002509TEST(SSLTest, TLS13ExporterAvailability) {
2510 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2511 bssl::UniquePtr<SSL_CTX> server_ctx =
2512 CreateContextWithTestCertificate(TLS_method());
2513 ASSERT_TRUE(client_ctx);
2514 ASSERT_TRUE(server_ctx);
2515 // Configure only TLS 1.3.
2516 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
2517 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2518
2519 bssl::UniquePtr<SSL> client, server;
2520 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2521 server_ctx.get()));
2522
2523 std::vector<uint8_t> buffer(32);
2524 const char *label = "EXPORTER-test-label";
2525
2526 // The exporters are not available before the handshake starts.
2527 EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2528 buffer.size(), label, strlen(label),
2529 nullptr, 0, 0));
2530 EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(),
2531 buffer.size(), label, strlen(label),
2532 nullptr, 0, 0));
2533
2534 // Send the client's first flight of handshake messages.
2535 int client_ret = SSL_do_handshake(client.get());
2536 EXPECT_EQ(SSL_get_error(client.get(), client_ret), SSL_ERROR_WANT_READ);
2537
2538 // The handshake isn't far enough for the exporters to work.
2539 EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2540 buffer.size(), label, strlen(label),
2541 nullptr, 0, 0));
2542 EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(),
2543 buffer.size(), label, strlen(label),
2544 nullptr, 0, 0));
2545
2546 // Send all the server's handshake messages.
2547 int server_ret = SSL_do_handshake(server.get());
2548 EXPECT_EQ(SSL_get_error(server.get(), server_ret), SSL_ERROR_WANT_READ);
2549
2550 // At this point in the handshake, the server should have the exporter key
2551 // derived since it's sent its Finished message. The client hasn't yet
2552 // processed the server's handshake messages, so the exporter shouldn't be
2553 // available to the client.
2554 EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2555 buffer.size(), label, strlen(label),
2556 nullptr, 0, 0));
2557 EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2558 buffer.size(), label, strlen(label),
2559 nullptr, 0, 0));
2560
2561 // Finish the handshake on the client.
2562 EXPECT_EQ(SSL_do_handshake(client.get()), 1);
2563
2564 // The exporter should be available on both endpoints.
2565 EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(),
2566 buffer.size(), label, strlen(label),
2567 nullptr, 0, 0));
2568 EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2569 buffer.size(), label, strlen(label),
2570 nullptr, 0, 0));
2571
2572 // Finish the handshake on the server.
2573 EXPECT_EQ(SSL_do_handshake(server.get()), 1);
2574
2575 // The exporter should still be available on both endpoints.
2576 EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(),
2577 buffer.size(), label, strlen(label),
2578 nullptr, 0, 0));
2579 EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2580 buffer.size(), label, strlen(label),
2581 nullptr, 0, 0));
2582}
2583
David Benjaminc79ae7a2017-08-29 16:09:44 -04002584static void AppendSession(SSL_SESSION *session, void *arg) {
2585 std::vector<SSL_SESSION*> *out =
2586 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2587 out->push_back(session);
2588}
2589
2590// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2591// order.
2592static bool CacheEquals(SSL_CTX *ctx,
2593 const std::vector<SSL_SESSION*> &expected) {
2594 // Check the linked list.
2595 SSL_SESSION *ptr = ctx->session_cache_head;
2596 for (SSL_SESSION *session : expected) {
2597 if (ptr != session) {
2598 return false;
2599 }
2600 // TODO(davidben): This is an absurd way to denote the end of the list.
2601 if (ptr->next ==
2602 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2603 ptr = nullptr;
2604 } else {
2605 ptr = ptr->next;
2606 }
2607 }
2608 if (ptr != nullptr) {
2609 return false;
2610 }
2611
2612 // Check the hash table.
2613 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002614 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002615 expected_copy = expected;
2616
2617 std::sort(actual.begin(), actual.end());
2618 std::sort(expected_copy.begin(), expected_copy.end());
2619
2620 return actual == expected_copy;
2621}
2622
2623static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2624 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2625 if (!ssl_ctx) {
2626 return nullptr;
2627 }
2628 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2629 if (!ret) {
2630 return nullptr;
2631 }
2632
David Benjaminaaef8332018-06-29 16:45:49 -04002633 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2634 OPENSSL_memcpy(id, &number, sizeof(number));
2635 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2636 return nullptr;
2637 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002638 return ret;
2639}
2640
2641// Test that the internal session cache behaves as expected.
2642TEST(SSLTest, InternalSessionCache) {
2643 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2644 ASSERT_TRUE(ctx);
2645
2646 // Prepare 10 test sessions.
2647 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2648 for (int i = 0; i < 10; i++) {
2649 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2650 ASSERT_TRUE(session);
2651 sessions.push_back(std::move(session));
2652 }
2653
2654 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2655
2656 // Insert all the test sessions.
2657 for (const auto &session : sessions) {
2658 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2659 }
2660
2661 // Only the last five should be in the list.
2662 ASSERT_TRUE(CacheEquals(
2663 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2664 sessions[6].get(), sessions[5].get()}));
2665
2666 // Inserting an element already in the cache should fail and leave the cache
2667 // unchanged.
2668 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2669 ASSERT_TRUE(CacheEquals(
2670 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2671 sessions[6].get(), sessions[5].get()}));
2672
2673 // Although collisions should be impossible (256-bit session IDs), the cache
2674 // must handle them gracefully.
2675 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2676 ASSERT_TRUE(collision);
2677 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2678 ASSERT_TRUE(CacheEquals(
2679 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2680 sessions[6].get(), sessions[5].get()}));
2681
2682 // Removing sessions behaves correctly.
2683 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2684 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2685 sessions[8].get(), sessions[5].get()}));
2686
2687 // Removing sessions requires an exact match.
2688 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2689 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2690
2691 // The cache remains unchanged.
2692 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2693 sessions[8].get(), sessions[5].get()}));
2694}
2695
2696static uint16_t EpochFromSequence(uint64_t seq) {
2697 return static_cast<uint16_t>(seq >> 48);
2698}
2699
David Benjamin71dfad42017-07-16 17:27:39 -04002700static const uint8_t kTestName[] = {
2701 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2702 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2703 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2704 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2705 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2706 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2707};
2708
David Benjaminc11ea9422017-08-29 16:33:21 -04002709// SSLVersionTest executes its test cases under all available protocol versions.
2710// Test cases call |Connect| to create a connection using context objects with
2711// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002712class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2713 protected:
2714 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2715
2716 void SetUp() { ResetContexts(); }
2717
2718 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2719 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2720 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2721 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2722 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2723 return nullptr;
2724 }
2725 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002726 }
David Benjamin686bb192016-05-10 15:15:41 -04002727
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002728 void ResetContexts() {
2729 ASSERT_TRUE(cert_);
2730 ASSERT_TRUE(key_);
2731 client_ctx_ = CreateContext();
2732 ASSERT_TRUE(client_ctx_);
2733 server_ctx_ = CreateContext();
2734 ASSERT_TRUE(server_ctx_);
2735 // Set up a server cert. Client certs can be set up explicitly.
2736 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002737 }
David Benjamin686bb192016-05-10 15:15:41 -04002738
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002739 bool UseCertAndKey(SSL_CTX *ctx) const {
2740 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2741 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002742 }
David Benjamin686bb192016-05-10 15:15:41 -04002743
David Benjamina8614602017-09-06 15:40:19 -04002744 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002745 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002746 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002747 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002748 }
2749
2750 uint16_t version() const { return GetParam().version; }
2751
2752 bool is_dtls() const {
2753 return GetParam().ssl_method == VersionParam::is_dtls;
2754 }
2755
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002756 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002757 bssl::UniquePtr<SSL> client_, server_;
2758 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2759 bssl::UniquePtr<X509> cert_;
2760 bssl::UniquePtr<EVP_PKEY> key_;
2761};
2762
David Benjaminbe7006a2019-04-09 18:05:02 -05002763INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2764 testing::ValuesIn(kAllVersions),
2765 [](const testing::TestParamInfo<VersionParam> &i) {
2766 return i.param.name;
2767 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768
2769TEST_P(SSLVersionTest, SequenceNumber) {
2770 ASSERT_TRUE(Connect());
2771
David Benjamin0fef3052016-11-18 15:11:10 +09002772 // Drain any post-handshake messages to ensure there are no unread records
2773 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002774 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002775
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002776 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2777 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2778 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2779 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002780
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002781 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002782 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002783 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2784 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2785 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2786 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002787
2788 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 EXPECT_GT(client_write_seq, server_read_seq);
2790 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002791 } else {
2792 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002793 EXPECT_EQ(client_write_seq, server_read_seq);
2794 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002795 }
2796
2797 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002798 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2800 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002801
2802 // The client write and server read sequence numbers should have
2803 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2805 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002806}
2807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002809 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002810 if (is_dtls()) {
2811 return;
David Benjamin686bb192016-05-10 15:15:41 -04002812 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002813 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002814
David Benjamin9734e442021-06-15 13:58:12 -04002815 // Shut down half the connection. |SSL_shutdown| will return 0 to signal only
David Benjamin686bb192016-05-10 15:15:41 -04002816 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002817 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002818
2819 // Reading from the server should consume the EOF.
2820 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002821 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2822 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002823
2824 // However, the server may continue to write data and then shut down the
2825 // connection.
2826 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002827 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2828 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2829 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002830
2831 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2833 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002834}
David Benjamin68f37b72016-11-18 15:14:42 +09002835
David Benjamin9734e442021-06-15 13:58:12 -04002836// Test that, after calling |SSL_shutdown|, |SSL_write| fails.
2837TEST_P(SSLVersionTest, WriteAfterShutdown) {
2838 ASSERT_TRUE(Connect());
2839
2840 for (SSL *ssl : {client_.get(), server_.get()}) {
2841 SCOPED_TRACE(SSL_is_server(ssl) ? "server" : "client");
2842
2843 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2844 ASSERT_TRUE(mem);
2845 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2846
2847 // Shut down half the connection. |SSL_shutdown| will return 0 to signal
2848 // only one side has shut down.
2849 ASSERT_EQ(SSL_shutdown(ssl), 0);
2850
2851 // |ssl| should have written an alert to the transport.
2852 const uint8_t *unused;
2853 size_t len;
2854 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2855 EXPECT_NE(0u, len);
2856 EXPECT_TRUE(BIO_reset(mem.get()));
2857
2858 // Writing should fail.
2859 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2860
2861 // Nothing should be written to the transport.
2862 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2863 EXPECT_EQ(0u, len);
2864 }
2865}
2866
2867// Test that, after sending a fatal alert in a failed |SSL_read|, |SSL_write|
2868// fails.
2869TEST_P(SSLVersionTest, WriteAfterReadSentFatalAlert) {
2870 // Decryption failures are not fatal in DTLS.
2871 if (is_dtls()) {
2872 return;
2873 }
2874
2875 ASSERT_TRUE(Connect());
2876
2877 // Save the write |BIO|s as the test will overwrite them.
2878 bssl::UniquePtr<BIO> client_wbio = bssl::UpRef(SSL_get_wbio(client_.get()));
2879 bssl::UniquePtr<BIO> server_wbio = bssl::UpRef(SSL_get_wbio(server_.get()));
2880
2881 for (bool test_server : {false, true}) {
2882 SCOPED_TRACE(test_server ? "server" : "client");
2883 SSL *ssl = test_server ? server_.get() : client_.get();
2884 BIO *other_wbio = test_server ? client_wbio.get() : server_wbio.get();
2885
2886 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2887 ASSERT_TRUE(mem);
2888 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2889
2890 // Read an invalid record from the peer.
2891 static const uint8_t kInvalidRecord[] = "invalid record";
2892 EXPECT_EQ(int{sizeof(kInvalidRecord)},
2893 BIO_write(other_wbio, kInvalidRecord, sizeof(kInvalidRecord)));
2894 char buf[256];
2895 EXPECT_EQ(-1, SSL_read(ssl, buf, sizeof(buf)));
2896
2897 // |ssl| should have written an alert to the transport.
2898 const uint8_t *unused;
2899 size_t len;
2900 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2901 EXPECT_NE(0u, len);
2902 EXPECT_TRUE(BIO_reset(mem.get()));
2903
2904 // Writing should fail.
2905 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2906
2907 // Nothing should be written to the transport.
2908 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2909 EXPECT_EQ(0u, len);
2910 }
2911}
2912
2913// Test that, after sending a fatal alert from the handshake, |SSL_write| fails.
2914TEST_P(SSLVersionTest, WriteAfterHandshakeSentFatalAlert) {
2915 for (bool test_server : {false, true}) {
2916 SCOPED_TRACE(test_server ? "server" : "client");
2917
2918 bssl::UniquePtr<SSL> ssl(
2919 SSL_new(test_server ? server_ctx_.get() : client_ctx_.get()));
2920 ASSERT_TRUE(ssl);
2921 if (test_server) {
2922 SSL_set_accept_state(ssl.get());
2923 } else {
2924 SSL_set_connect_state(ssl.get());
2925 }
2926
2927 std::vector<uint8_t> invalid;
2928 if (is_dtls()) {
2929 // In DTLS, invalid records are discarded. To cause the handshake to fail,
2930 // use a valid handshake record with invalid contents.
2931 invalid.push_back(SSL3_RT_HANDSHAKE);
2932 invalid.push_back(DTLS1_VERSION >> 8);
2933 invalid.push_back(DTLS1_VERSION & 0xff);
2934 // epoch and sequence_number
2935 for (int i = 0; i < 8; i++) {
2936 invalid.push_back(0);
2937 }
2938 // A one-byte fragment is invalid.
2939 invalid.push_back(0);
2940 invalid.push_back(1);
2941 // Arbitrary contents.
2942 invalid.push_back(0);
2943 } else {
2944 invalid = {'i', 'n', 'v', 'a', 'l', 'i', 'd'};
2945 }
2946 bssl::UniquePtr<BIO> rbio(
2947 BIO_new_mem_buf(invalid.data(), invalid.size()));
2948 ASSERT_TRUE(rbio);
2949 SSL_set0_rbio(ssl.get(), rbio.release());
2950
2951 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2952 ASSERT_TRUE(mem);
2953 SSL_set0_wbio(ssl.get(), bssl::UpRef(mem).release());
2954
2955 // The handshake should fail.
2956 EXPECT_EQ(-1, SSL_do_handshake(ssl.get()));
2957 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2958 uint32_t err = ERR_get_error();
2959
2960 // |ssl| should have written an alert (and, in the client's case, a
2961 // ClientHello) to the transport.
2962 const uint8_t *unused;
2963 size_t len;
2964 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2965 EXPECT_NE(0u, len);
2966 EXPECT_TRUE(BIO_reset(mem.get()));
2967
2968 // Writing should fail, with the same error as the handshake.
2969 EXPECT_EQ(-1, SSL_write(ssl.get(), "a", 1));
2970 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2971 EXPECT_EQ(err, ERR_get_error());
2972
2973 // Nothing should be written to the transport.
2974 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2975 EXPECT_EQ(0u, len);
2976 }
2977}
2978
2979// Test that, after seeing TLS 1.2 in response to early data, |SSL_write|
2980// continues to report |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. See
2981// https://crbug.com/1078515.
2982TEST(SSLTest, WriteAfterWrongVersionOnEarlyData) {
2983 // Set up some 0-RTT-enabled contexts.
2984 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2985 bssl::UniquePtr<SSL_CTX> server_ctx =
2986 CreateContextWithTestCertificate(TLS_method());
2987 ASSERT_TRUE(client_ctx);
2988 ASSERT_TRUE(server_ctx);
2989 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
2990 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
2991 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2992 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2993
2994 // Get an early-data-capable session.
2995 bssl::UniquePtr<SSL_SESSION> session =
2996 CreateClientSession(client_ctx.get(), server_ctx.get());
2997 ASSERT_TRUE(session);
2998 EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
2999
3000 // Offer the session to the server, but now the server speaks TLS 1.2.
3001 bssl::UniquePtr<SSL> client, server;
3002 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
3003 server_ctx.get()));
3004 SSL_set_session(client.get(), session.get());
3005 EXPECT_TRUE(SSL_set_max_proto_version(server.get(), TLS1_2_VERSION));
3006
3007 // The client handshake initially succeeds in the early data state.
3008 EXPECT_EQ(1, SSL_do_handshake(client.get()));
3009 EXPECT_TRUE(SSL_in_early_data(client.get()));
3010
3011 // The server processes the ClientHello and negotiates TLS 1.2.
3012 EXPECT_EQ(-1, SSL_do_handshake(server.get()));
3013 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server.get(), -1));
3014 EXPECT_EQ(TLS1_2_VERSION, SSL_version(server.get()));
3015
3016 // Capture the client's output.
3017 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
3018 ASSERT_TRUE(mem);
3019 SSL_set0_wbio(client.get(), bssl::UpRef(mem).release());
3020
3021 // The client processes the ServerHello and fails.
3022 EXPECT_EQ(-1, SSL_do_handshake(client.get()));
3023 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
David Benjaminec2a08d2024-02-21 23:21:16 -05003024 EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
3025 SSL_R_WRONG_VERSION_ON_EARLY_DATA));
David Benjamin9734e442021-06-15 13:58:12 -04003026
3027 // The client should have written an alert to the transport.
3028 const uint8_t *unused;
3029 size_t len;
3030 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3031 EXPECT_NE(0u, len);
3032 EXPECT_TRUE(BIO_reset(mem.get()));
3033
3034 // Writing should fail, with the same error as the handshake.
3035 EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
3036 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
David Benjaminec2a08d2024-02-21 23:21:16 -05003037 EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
3038 SSL_R_WRONG_VERSION_ON_EARLY_DATA));
David Benjamin9734e442021-06-15 13:58:12 -04003039
3040 // Nothing should be written to the transport.
3041 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3042 EXPECT_EQ(0u, len);
3043}
3044
David Benjaminf0d8e222017-02-04 10:58:26 -05003045TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003046 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04003047 bssl::UniquePtr<SSL_CTX> server_ctx =
3048 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05003049 ASSERT_TRUE(client_ctx);
3050 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04003051
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003052 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003053 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003054 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04003055
3056 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04003057 bssl::UniquePtr<SSL_SESSION> session1 =
3058 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05003059 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04003060
David Benjamina3a71e92018-06-29 13:24:45 -04003061 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04003062
Steven Valdez87eab492016-06-27 16:34:59 -04003063 uint8_t *s0_bytes, *s1_bytes;
3064 size_t s0_len, s1_len;
3065
David Benjaminf0d8e222017-02-04 10:58:26 -05003066 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003067 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04003068
David Benjaminf0d8e222017-02-04 10:58:26 -05003069 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003070 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04003071
David Benjamin7d7554b2017-02-04 11:48:59 -05003072 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04003073}
David Benjamin686bb192016-05-10 15:15:41 -04003074
David Benjaminf0d8e222017-02-04 10:58:26 -05003075static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04003076 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05003077 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
3078 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04003079
3080 // The wrapper BIOs are always equal when fds are equal, even if set
3081 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05003082 if (rfd == wfd) {
3083 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04003084 }
David Benjamin5c0fb882016-06-14 14:03:51 -04003085}
3086
David Benjaminf0d8e222017-02-04 10:58:26 -05003087TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003088 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003089 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04003090
3091 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003092 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003093 ASSERT_TRUE(ssl);
3094 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3095 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
3096 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04003097
3098 // Test setting the same FD.
3099 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003100 ASSERT_TRUE(ssl);
3101 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3102 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003103
3104 // Test setting the same FD one side at a time.
3105 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003106 ASSERT_TRUE(ssl);
3107 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3108 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3109 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003110
3111 // Test setting the same FD in the other order.
3112 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003113 ASSERT_TRUE(ssl);
3114 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3115 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3116 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003117
David Benjamin5c0fb882016-06-14 14:03:51 -04003118 // Test changing the read FD partway through.
3119 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003120 ASSERT_TRUE(ssl);
3121 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3122 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
3123 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003124
3125 // Test changing the write FD partway through.
3126 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003127 ASSERT_TRUE(ssl);
3128 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3129 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
3130 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04003131
3132 // Test a no-op change to the read FD partway through.
3133 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003134 ASSERT_TRUE(ssl);
3135 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3136 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3137 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003138
3139 // Test a no-op change to the write FD partway through.
3140 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003141 ASSERT_TRUE(ssl);
3142 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3143 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3144 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04003145
3146 // ASan builds will implicitly test that the internal |BIO| reference-counting
3147 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04003148}
3149
David Benjaminf0d8e222017-02-04 10:58:26 -05003150TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003151 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003152 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04003153
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003154 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3155 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04003156 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003157 ASSERT_TRUE(ssl);
3158 ASSERT_TRUE(bio1);
3159 ASSERT_TRUE(bio2);
3160 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04003161
3162 // SSL_set_bio takes one reference when the parameters are the same.
3163 BIO_up_ref(bio1.get());
3164 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3165
3166 // Repeating the call does nothing.
3167 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3168
3169 // It takes one reference each when the parameters are different.
3170 BIO_up_ref(bio2.get());
3171 BIO_up_ref(bio3.get());
3172 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
3173
3174 // Repeating the call does nothing.
3175 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
3176
3177 // It takes one reference when changing only wbio.
3178 BIO_up_ref(bio1.get());
3179 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
3180
3181 // It takes one reference when changing only rbio and the two are different.
3182 BIO_up_ref(bio3.get());
3183 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
3184
3185 // If setting wbio to rbio, it takes no additional references.
3186 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
3187
3188 // From there, wbio may be switched to something else.
3189 BIO_up_ref(bio1.get());
3190 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
3191
3192 // If setting rbio to wbio, it takes no additional references.
3193 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3194
3195 // From there, rbio may be switched to something else, but, for historical
3196 // reasons, it takes a reference to both parameters.
3197 BIO_up_ref(bio1.get());
3198 BIO_up_ref(bio2.get());
3199 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
3200
3201 // ASAN builds will implicitly test that the internal |BIO| reference-counting
3202 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04003203}
3204
David Benjamin25490f22016-07-14 00:22:54 -04003205static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
3206
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003207TEST_P(SSLVersionTest, GetPeerCertificate) {
3208 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04003209
David Benjamin0fef3052016-11-18 15:11:10 +09003210 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003211 SSL_CTX_set_verify(client_ctx_.get(),
3212 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3213 nullptr);
3214 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3215 SSL_CTX_set_verify(server_ctx_.get(),
3216 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3217 nullptr);
3218 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04003219
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003220 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04003221
David Benjamin0fef3052016-11-18 15:11:10 +09003222 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003223 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3224 ASSERT_TRUE(peer);
3225 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04003226
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003227 peer.reset(SSL_get_peer_certificate(client_.get()));
3228 ASSERT_TRUE(peer);
3229 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04003230
David Benjamine664a532017-07-20 20:19:36 -04003231 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09003232 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003233 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
3234 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
3235 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04003236
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003237 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
3238 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
3239 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04003240}
3241
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003242TEST_P(SSLVersionTest, NoPeerCertificate) {
3243 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
3244 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3245 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04003246
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003247 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04003248
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003249 // Server should not see a peer certificate.
3250 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3251 ASSERT_FALSE(peer);
3252 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04003253}
3254
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003255TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04003256 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003257 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
3258 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003259 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04003260
3261 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
3262 SHA256(cert_der, cert_der_len, cert_sha256);
3263
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003264 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3265
David Benjamin0fef3052016-11-18 15:11:10 +09003266 // Configure both client and server to accept any certificate, but the
3267 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003268 SSL_CTX_set_verify(client_ctx_.get(),
3269 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3270 nullptr);
3271 SSL_CTX_set_verify(server_ctx_.get(),
3272 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3273 nullptr);
3274 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3275 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3276 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04003277
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003278 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04003279
David Benjamin0fef3052016-11-18 15:11:10 +09003280 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003281 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3282 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04003283
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003284 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04003285 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04003286
David Benjamin02de7bd2018-05-08 18:13:54 -04003287 const uint8_t *peer_sha256;
3288 size_t peer_sha256_len;
3289 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
3290 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04003291}
3292
David Benjamin737d2df2017-09-25 15:05:19 -04003293// Tests that our ClientHellos do not change unexpectedly. These are purely
3294// change detection tests. If they fail as part of an intentional ClientHello
3295// change, update the test vector.
3296TEST(SSLTest, ClientHello) {
3297 struct {
3298 uint16_t max_version;
3299 std::vector<uint8_t> expected;
3300 } kTests[] = {
David Benjaminb0251b12023-04-21 17:56:08 -04003301 {TLS1_VERSION,
3302 {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00,
3303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09,
3306 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00,
3307 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
3308 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
3309 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
3310 {TLS1_1_VERSION,
3311 {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x02, 0x00,
3312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09,
3315 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00,
3316 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
3317 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
3318 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
3319 {TLS1_2_VERSION,
3320 {0x16, 0x03, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x7c, 0x03, 0x03, 0x00,
3321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xcc, 0xa9,
3324 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
3325 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
3326 0x00, 0x35, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01,
3327 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
3328 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00,
3329 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
3330 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
3331 0x01}},
3332 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
3333 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02003334 };
David Benjamin737d2df2017-09-25 15:05:19 -04003335
3336 for (const auto &t : kTests) {
3337 SCOPED_TRACE(t.max_version);
3338
3339 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3340 ASSERT_TRUE(ctx);
3341 // Our default cipher list varies by CPU capabilities, so manually place the
3342 // ChaCha20 ciphers in front.
3343 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04003344 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
3345 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
3346
3347 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3348 ASSERT_TRUE(ssl);
3349 std::vector<uint8_t> client_hello;
3350 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
3351
3352 // Zero the client_random.
3353 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
3354 1 + 3 + // handshake message header
3355 2; // client_version
3356 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
3357 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
3358
3359 if (client_hello != t.expected) {
3360 ADD_FAILURE() << "ClientHellos did not match.";
3361 // Print the value manually so it is easier to update the test vector.
3362 for (size_t i = 0; i < client_hello.size(); i += 12) {
3363 printf(" %c", i == 0 ? '{' : ' ');
3364 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
3365 if (j > i) {
3366 printf(" ");
3367 }
3368 printf("0x%02x", client_hello[j]);
3369 if (j < client_hello.size() - 1) {
3370 printf(",");
3371 }
3372 }
3373 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07003374 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04003375 }
3376 printf("\n");
3377 }
3378 }
David Benjaminafc64de2016-07-19 17:12:41 +02003379 }
David Benjaminafc64de2016-07-19 17:12:41 +02003380}
3381
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003382static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
3383 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003384 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003385 ClientConfig config;
3386 config.session = session;
David Benjaminf7d37fb2023-02-04 19:45:04 -05003387 ASSERT_TRUE(
David Benjamina8614602017-09-06 15:40:19 -04003388 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04003389
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003390 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04003391
3392 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003393 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04003394}
3395
David Benjamin3c51d9b2016-11-01 17:50:42 -04003396static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
3397 SSL_CTX *server_ctx,
3398 SSL_SESSION *session) {
3399 g_last_session = nullptr;
3400 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
3401
3402 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003403 ClientConfig config;
3404 config.session = session;
3405 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05003406 config) ||
3407 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003408 fprintf(stderr, "Failed to connect client and server.\n");
3409 return nullptr;
3410 }
3411
3412 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
3413 fprintf(stderr, "Client and server were inconsistent.\n");
3414 return nullptr;
3415 }
3416
3417 if (!SSL_session_reused(client.get())) {
3418 fprintf(stderr, "Session was not reused.\n");
3419 return nullptr;
3420 }
3421
David Benjamin3c51d9b2016-11-01 17:50:42 -04003422 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
3423
3424 if (!g_last_session) {
3425 fprintf(stderr, "Client did not receive a renewed session.\n");
3426 return nullptr;
3427 }
3428 return std::move(g_last_session);
3429}
3430
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003431static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003432 bool changed) {
3433 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04003434 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003435 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
3436 if (changed) {
3437 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3438 } else {
3439 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003440 }
3441 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003442}
3443
David Benjamina933c382016-10-28 00:10:03 -04003444static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
3445 static const uint8_t kContext[] = {3};
3446
3447 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
3448 return SSL_TLSEXT_ERR_ALERT_FATAL;
3449 }
3450
3451 return SSL_TLSEXT_ERR_OK;
3452}
3453
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003454TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04003455 static const uint8_t kContext1[] = {1};
3456 static const uint8_t kContext2[] = {2};
3457
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003458 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3459 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04003460
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003461 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3462 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04003463
David Benjamin0fef3052016-11-18 15:11:10 +09003464 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003465 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3466 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04003467
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003468 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3469 session.get(),
3470 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003471
David Benjamin0fef3052016-11-18 15:11:10 +09003472 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003473 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
3474 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04003475
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003476 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3477 session.get(),
3478 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003479
David Benjamin0fef3052016-11-18 15:11:10 +09003480 // Change the session ID context back and install an SNI callback to switch
3481 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003482 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3483 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04003484
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003485 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003486 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04003487
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003488 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3489 session.get(),
3490 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003491
David Benjamin0fef3052016-11-18 15:11:10 +09003492 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003493 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003494 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003495 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003496 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3497 static const uint8_t kContext[] = {3};
3498
3499 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
3500 sizeof(kContext))) {
3501 return ssl_select_cert_error;
3502 }
3503
3504 return ssl_select_cert_success;
3505 });
David Benjamina933c382016-10-28 00:10:03 -04003506
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003507 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3508 session.get(),
3509 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003510}
3511
David Benjamin721e8b72016-08-03 13:13:17 -04003512static timeval g_current_time;
3513
3514static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
3515 *out_clock = g_current_time;
3516}
3517
David Benjamin17b30832017-01-28 14:00:32 -05003518static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
3519 out_clock->tv_sec = 1000;
3520 out_clock->tv_usec = 0;
3521}
3522
David Benjamin3c51d9b2016-11-01 17:50:42 -04003523static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
3524 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
3525 int encrypt) {
3526 static const uint8_t kZeros[16] = {0};
3527
3528 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05003529 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04003530 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05003531 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003532 return 0;
3533 }
3534
3535 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
3536 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
3537 return -1;
3538 }
3539
3540 // Returning two from the callback in decrypt mode renews the
3541 // session in TLS 1.2 and below.
3542 return encrypt ? 1 : 2;
3543}
3544
David Benjamin123db572016-11-03 16:59:25 -04003545static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04003546 const uint8_t *ticket;
3547 size_t ticket_len;
3548 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
3549 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04003550 return false;
3551 }
3552
David Benjaminaaef8332018-06-29 16:45:49 -04003553 const uint8_t *ciphertext = ticket + 16 + 16;
3554 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamina36ac0a2023-07-04 12:48:02 -04003555 auto plaintext = std::make_unique<uint8_t[]>(len);
David Benjamin123db572016-11-03 16:59:25 -04003556
David Benjamin9b63f292016-11-15 00:44:05 -05003557#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3558 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05003559 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05003560#else
3561 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04003562 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04003563 bssl::ScopedEVP_CIPHER_CTX ctx;
3564 int len1, len2;
David Benjamina4385192023-03-25 01:26:49 -04003565 if (len > INT_MAX ||
3566 !EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
3567 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext,
3568 static_cast<int>(len)) ||
David Benjamin123db572016-11-03 16:59:25 -04003569 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
3570 return false;
3571 }
3572
3573 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05003574#endif
David Benjamin123db572016-11-03 16:59:25 -04003575
Adam Langley46db7af2017-02-01 15:49:37 -08003576 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
3577 if (!ssl_ctx) {
3578 return false;
3579 }
David Benjamin123db572016-11-03 16:59:25 -04003580 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08003581 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04003582 if (!server_session) {
3583 return false;
3584 }
3585
David Benjaminaaef8332018-06-29 16:45:49 -04003586 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04003587 return true;
3588}
3589
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003590TEST_P(SSLVersionTest, SessionTimeout) {
3591 for (bool server_test : {false, true}) {
3592 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04003593
David Benjaminf7d37fb2023-02-04 19:45:04 -05003594 ASSERT_NO_FATAL_FAILURE(ResetContexts());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003595 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3596 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3597
David Benjamin17b30832017-01-28 14:00:32 -05003598 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09003599 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04003600
David Benjamin17b30832017-01-28 14:00:32 -05003601 // We are willing to use a longer lifetime for TLS 1.3 sessions as
3602 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003603 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05003604 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
3605 : SSL_DEFAULT_SESSION_TIMEOUT;
3606
David Benjamin17b30832017-01-28 14:00:32 -05003607 // Both client and server must enforce session timeouts. We configure the
3608 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09003609 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003610 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3611 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003612 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003613 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
3614 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003615 }
3616
3617 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003618 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003619
3620 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003621 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3622 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09003623
3624 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05003625 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09003626
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003627 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3628 session.get(),
3629 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003630
3631 // Advance the clock one more second.
3632 g_current_time.tv_sec++;
3633
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003634 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3635 session.get(),
3636 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003637
3638 // Rewind the clock to before the session was minted.
3639 g_current_time.tv_sec = kStartTime - 1;
3640
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003641 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3642 session.get(),
3643 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003644
David Benjamin0fef3052016-11-18 15:11:10 +09003645 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05003646 time_t new_start_time = kStartTime + timeout - 10;
3647 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003648 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
3649 client_ctx_.get(), server_ctx_.get(), session.get());
3650 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09003651
3652 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003653 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003654
3655 // Check the sessions have timestamps measured from issuance.
3656 long session_time = 0;
3657 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003658 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003659 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003660 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003661 }
David Benjamin721e8b72016-08-03 13:13:17 -04003662
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003663 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003664
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003665 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003666 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3667 // lifetime TLS 1.3.
3668 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003669 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3670 new_session.get(),
3671 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003672
David Benjamin17b30832017-01-28 14:00:32 -05003673 // The new session expires after the new timeout.
3674 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003675 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3676 new_session.get(),
3677 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003678
3679 // Renew the session until it begins just past the auth timeout.
3680 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3681 while (new_start_time < auth_end_time - 1000) {
3682 // Get as close as possible to target start time.
3683 new_start_time =
3684 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3685 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003686 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003687 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003688 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003689 }
3690
3691 // Now the session's lifetime is bound by the auth timeout.
3692 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003693 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3694 new_session.get(),
3695 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003696
3697 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003698 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3699 new_session.get(),
3700 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003701 } else {
3702 // The new session is usable just before the old expiration.
3703 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003704 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3705 new_session.get(),
3706 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003707
3708 // Renewal does not extend the lifetime, so it is not usable beyond the
3709 // old expiration.
3710 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003711 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3712 new_session.get(),
3713 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003714 }
David Benjamin721e8b72016-08-03 13:13:17 -04003715 }
David Benjamin721e8b72016-08-03 13:13:17 -04003716}
3717
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003718TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003719 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3720 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003721 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003722 kTicketKeyLen));
3723 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3724}
3725
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003726TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003727 static const time_t kStartTime = 1001;
3728 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003729
David Benjaminc11ea9422017-08-29 16:33:21 -04003730 // We use session reuse as a proxy for ticket decryption success, hence
3731 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003732 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3733 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003734 std::numeric_limits<uint32_t>::max());
3735
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003736 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3737 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003738
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003739 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3740 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003741
David Benjamin1f0d54b2018-08-09 16:19:13 -05003742 // Initialize ticket_key with the current key and check that it was
3743 // initialized to something, not all zeros.
3744 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003745 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3746 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003747
David Benjaminc11ea9422017-08-29 16:33:21 -04003748 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003749 bssl::UniquePtr<SSL> client, server;
3750 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003751 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003752 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003753 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003754 session.get(), true /* reused */));
3755
David Benjaminc11ea9422017-08-29 16:33:21 -04003756 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003757 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003758 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003759 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003760 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003761 false /* NOT changed */));
3762
David Benjaminc11ea9422017-08-29 16:33:21 -04003763 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003764 g_current_time.tv_sec += 1;
3765 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003766 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3767 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3768 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003769
David Benjaminc11ea9422017-08-29 16:33:21 -04003770 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003771 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003772 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003773 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003774 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003775 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003776 false /* NOT changed */));
3777
David Benjaminc11ea9422017-08-29 16:33:21 -04003778 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003779 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003780 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003781 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003782 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3783 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003784
David Benjaminc11ea9422017-08-29 16:33:21 -04003785 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003786 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003787 new_session.get(), true /* reused */));
3788}
3789
David Benjamin0fc37ef2016-08-17 15:29:46 -04003790static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003791 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003792 SSL_set_SSL_CTX(ssl, ctx);
3793 return SSL_TLSEXT_ERR_OK;
3794}
3795
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003796TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003797 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003798 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003799 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003800 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003801
David Benjamin0fef3052016-11-18 15:11:10 +09003802 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3803 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003804
David Benjamin83a32122017-02-14 18:34:54 -05003805 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3806 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003808 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3809 ASSERT_TRUE(server_ctx2);
3810 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3811 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3812 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3813 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3814 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3815 sizeof(kOCSPResponse)));
3816 // Historically signing preferences would be lost in some cases with the
3817 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3818 // this doesn't happen when |version| is TLS 1.2, configure the private
3819 // key to only sign SHA-256.
3820 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3821 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003822
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003823 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3824 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003825
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003826 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3827 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003828
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003829 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003830
David Benjamin0fef3052016-11-18 15:11:10 +09003831 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003832 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3833 ASSERT_TRUE(peer);
3834 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003835
David Benjamin83a32122017-02-14 18:34:54 -05003836 // The client should have received |server_ctx2|'s SCT list.
3837 const uint8_t *data;
3838 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003839 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3840 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003841
3842 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003843 SSL_get0_ocsp_response(client_.get(), &data, &len);
3844 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003845}
3846
David Benjaminf0d8e222017-02-04 10:58:26 -05003847// Test that the early callback can swap the maximum version.
3848TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003849 bssl::UniquePtr<SSL_CTX> server_ctx =
3850 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003851 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003852 ASSERT_TRUE(server_ctx);
3853 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003854 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3855 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003856
David Benjaminf0d8e222017-02-04 10:58:26 -05003857 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003858 server_ctx.get(),
3859 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003860 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003861 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003862 }
3863
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003864 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003865 });
David Benjamin99620572016-08-30 00:35:36 -04003866
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003867 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003868 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003869 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003870 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003871}
3872
David Benjaminf0d8e222017-02-04 10:58:26 -05003873TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003874 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003875 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003876
David Benjaminf0d8e222017-02-04 10:58:26 -05003877 // Set valid TLS versions.
David Benjamin7a4df8e2021-10-14 13:56:03 -04003878 for (const auto &vers : kAllVersions) {
3879 SCOPED_TRACE(vers.name);
3880 if (vers.ssl_method == VersionParam::is_tls) {
3881 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3882 EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3883 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3884 EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3885 }
3886 }
David Benjamin2dc02042016-09-19 19:57:37 -04003887
David Benjaminf0d8e222017-02-04 10:58:26 -05003888 // Invalid TLS versions are rejected.
3889 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3890 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3891 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3892 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3893 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3894 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003895
David Benjaminf0d8e222017-02-04 10:58:26 -05003896 // Zero is the default version.
3897 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003898 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003899 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003900 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003901
David Benjamin9bb15f52018-06-26 00:07:40 -04003902 // SSL 3.0 is not available.
3903 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3904
David Benjamin2dc02042016-09-19 19:57:37 -04003905 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003906 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003907
David Benjamin7a4df8e2021-10-14 13:56:03 -04003908 // Set valid DTLS versions.
3909 for (const auto &vers : kAllVersions) {
3910 SCOPED_TRACE(vers.name);
3911 if (vers.ssl_method == VersionParam::is_dtls) {
3912 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3913 EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3914 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3915 EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3916 }
3917 }
David Benjamin2dc02042016-09-19 19:57:37 -04003918
David Benjamin7a4df8e2021-10-14 13:56:03 -04003919 // Invalid DTLS versions are rejected.
David Benjaminf0d8e222017-02-04 10:58:26 -05003920 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3921 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3922 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3923 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3924 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3925 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3926 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3927 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003928
David Benjamin7a4df8e2021-10-14 13:56:03 -04003929 // Zero is the default version.
David Benjaminf0d8e222017-02-04 10:58:26 -05003930 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003931 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003932 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003933 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003934}
3935
David Benjamin458334a2016-12-15 13:53:25 -05003936static const char *GetVersionName(uint16_t version) {
3937 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003938 case TLS1_VERSION:
3939 return "TLSv1";
3940 case TLS1_1_VERSION:
3941 return "TLSv1.1";
3942 case TLS1_2_VERSION:
3943 return "TLSv1.2";
3944 case TLS1_3_VERSION:
3945 return "TLSv1.3";
3946 case DTLS1_VERSION:
3947 return "DTLSv1";
3948 case DTLS1_2_VERSION:
3949 return "DTLSv1.2";
3950 default:
3951 return "???";
3952 }
3953}
3954
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003955TEST_P(SSLVersionTest, Version) {
3956 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003957
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003958 EXPECT_EQ(SSL_version(client_.get()), version());
3959 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003960
David Benjamin458334a2016-12-15 13:53:25 -05003961 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003962 const char *version_name = GetVersionName(version());
3963 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3964 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003965
3966 // Test SSL_SESSION reports the same name.
3967 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003968 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003969 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003970 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3971 EXPECT_EQ(strcmp(version_name, client_name), 0);
3972 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003973}
3974
David Benjamin9ef31f02016-10-31 18:01:13 -04003975// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3976// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003977TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003978 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3979
David Benjamin9ef31f02016-10-31 18:01:13 -04003980 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003981 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3982 sizeof(kALPNProtos)),
3983 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003984
3985 // The ALPN callback does not fail the handshake on error, so have the
3986 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003987 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003988 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003989 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003990 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3991 unsigned in_len, void *arg) -> int {
3992 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3993 if (SSL_get_pending_cipher(ssl) != nullptr &&
3994 SSL_version(ssl) == state->first) {
3995 state->second = true;
3996 }
3997 return SSL_TLSEXT_ERR_NOACK;
3998 },
3999 &callback_state);
4000
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004001 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09004002
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004003 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09004004}
4005
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004006TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05004007 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
4008 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004009 if (version() == TLS1_3_VERSION) {
4010 return;
David Benjaminb79cc842016-12-07 15:57:14 -05004011 }
4012
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07004013 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004014 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05004015
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004016 EXPECT_FALSE(SSL_session_reused(client_.get()));
4017 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05004018
4019 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004020 ASSERT_TRUE(SSL_clear(client_.get()));
4021 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05004022
4023 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004024 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05004025
4026 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004027 EXPECT_TRUE(SSL_session_reused(client_.get()));
4028 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05004029}
4030
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07004031TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
4032 shed_handshake_config_ = false;
4033 ASSERT_TRUE(Connect());
4034 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
4035
4036 // Reset everything.
4037 ASSERT_TRUE(SSL_clear(client_.get()));
4038 ASSERT_TRUE(SSL_clear(server_.get()));
4039
4040 // Now enable shedding, and connect a second time.
4041 shed_handshake_config_ = true;
4042 ASSERT_TRUE(Connect());
4043 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
4044
4045 // |SSL_clear| should now fail.
4046 ASSERT_FALSE(SSL_clear(client_.get()));
4047 ASSERT_FALSE(SSL_clear(server_.get()));
4048}
4049
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004050static bool ChainsEqual(STACK_OF(X509) * chain,
4051 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05004052 if (sk_X509_num(chain) != expected.size()) {
4053 return false;
4054 }
4055
4056 for (size_t i = 0; i < expected.size(); i++) {
4057 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
4058 return false;
4059 }
4060 }
4061
4062 return true;
4063}
4064
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004065TEST_P(SSLVersionTest, AutoChain) {
4066 cert_ = GetChainTestCertificate();
4067 ASSERT_TRUE(cert_);
4068 key_ = GetChainTestKey();
4069 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05004070 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004071 ASSERT_TRUE(intermediate);
4072
4073 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4074 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05004075
4076 // Configure both client and server to accept any certificate. Add
4077 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004078 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
4079 intermediate.get()));
4080 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
4081 intermediate.get()));
4082 SSL_CTX_set_verify(client_ctx_.get(),
4083 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
4084 nullptr);
4085 SSL_CTX_set_verify(server_ctx_.get(),
4086 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
4087 nullptr);
4088 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
4089 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05004090
4091 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004092 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05004093
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004094 EXPECT_TRUE(
4095 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
4096 EXPECT_TRUE(
4097 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05004098
4099 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004100 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
4101 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
4102 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05004103
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004104 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
4105 {cert_.get(), intermediate.get()}));
4106 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
4107 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05004108
4109 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004110 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
4111 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
4112 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05004113
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004114 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
4115 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05004116
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004117 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
4118 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05004119}
4120
David Benjamin64bf8c52022-07-22 15:49:45 -07004121static bool ExpectSingleError(int lib, int reason) {
4122 const char *expected = ERR_reason_error_string(ERR_PACK(lib, reason));
David Benjamin48063c22017-01-01 23:56:36 -05004123 int err = ERR_get_error();
David Benjamin64bf8c52022-07-22 15:49:45 -07004124 if (ERR_GET_LIB(err) != lib || ERR_GET_REASON(err) != reason) {
David Benjamin48063c22017-01-01 23:56:36 -05004125 char buf[ERR_ERROR_STRING_BUF_LEN];
4126 ERR_error_string_n(err, buf, sizeof(buf));
David Benjamin64bf8c52022-07-22 15:49:45 -07004127 fprintf(stderr, "Wanted %s, got: %s.\n", expected, buf);
David Benjamin48063c22017-01-01 23:56:36 -05004128 return false;
4129 }
4130
4131 if (ERR_peek_error() != 0) {
David Benjamin64bf8c52022-07-22 15:49:45 -07004132 fprintf(stderr, "Unexpected error following %s.\n", expected);
David Benjamin48063c22017-01-01 23:56:36 -05004133 return false;
4134 }
4135
4136 return true;
4137}
4138
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004139TEST_P(SSLVersionTest, SSLWriteRetry) {
4140 if (is_dtls()) {
4141 return;
David Benjamin48063c22017-01-01 23:56:36 -05004142 }
4143
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004144 for (bool enable_partial_write : {false, true}) {
4145 SCOPED_TRACE(enable_partial_write);
4146
David Benjamin48063c22017-01-01 23:56:36 -05004147 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004148 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05004149
4150 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004151 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05004152 }
4153
4154 // Write without reading until the buffer is full and we have an unfinished
4155 // write. Keep a count so we may reread it again later. "hello!" will be
4156 // written in two chunks, "hello" and "!".
4157 char data[] = "hello!";
4158 static const int kChunkLen = 5; // The length of "hello".
4159 unsigned count = 0;
4160 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004161 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05004162 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004163 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
4164 break;
David Benjamin48063c22017-01-01 23:56:36 -05004165 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004166 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05004167 count++;
4168 }
4169
4170 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004171 ASSERT_EQ(
4172 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
4173 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05004174
4175 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004176 ASSERT_EQ(SSL_get_error(client_.get(),
4177 SSL_write(client_.get(), data, kChunkLen - 1)),
4178 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07004179 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05004180
4181 // Retrying with a different buffer pointer is not legal.
4182 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004183 ASSERT_EQ(SSL_get_error(client_.get(),
4184 SSL_write(client_.get(), data2, kChunkLen)),
4185 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07004186 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05004187
4188 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004189 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
4190 ASSERT_EQ(SSL_get_error(client_.get(),
4191 SSL_write(client_.get(), data2, kChunkLen)),
4192 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05004193
4194 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004195 ASSERT_EQ(SSL_get_error(client_.get(),
4196 SSL_write(client_.get(), data2, kChunkLen - 1)),
4197 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07004198 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05004199
4200 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004201 ASSERT_EQ(SSL_get_error(client_.get(),
4202 SSL_write(client_.get(), data, kChunkLen + 1)),
4203 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05004204
4205 // Drain the buffer.
4206 char buf[20];
4207 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004208 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4209 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05004210 }
4211
4212 // Now that there is space, a retry with a larger buffer should flush the
4213 // pending record, skip over that many bytes of input (on assumption they
4214 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
4215 // is set, this will complete in two steps.
David Benjamin64bf8c52022-07-22 15:49:45 -07004216 char data_longer[] = "_____!!!!!";
David Benjamin48063c22017-01-01 23:56:36 -05004217 if (enable_partial_write) {
David Benjamin64bf8c52022-07-22 15:49:45 -07004218 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4219 kChunkLen);
4220 ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4221 kChunkLen);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004222 } else {
David Benjamin64bf8c52022-07-22 15:49:45 -07004223 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4224 2 * kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05004225 }
4226
4227 // Check the last write was correct. The data will be spread over two
4228 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004229 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4230 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin64bf8c52022-07-22 15:49:45 -07004231 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4232 ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
4233
4234 // Fill the transport buffer again. This time only leave room for one
4235 // record.
4236 count = 0;
4237 for (;;) {
4238 int ret = SSL_write(client_.get(), data, kChunkLen);
4239 if (ret <= 0) {
4240 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
4241 break;
4242 }
4243 ASSERT_EQ(ret, 5);
4244 count++;
4245 }
4246 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4247 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4248 count--;
4249
4250 // Retry the last write, with a longer input. The first half is the most
4251 // recently failed write, from filling the buffer. |SSL_write| should write
4252 // that to the transport, and then attempt to write the second half.
4253 int ret = SSL_write(client_.get(), data_longer, 2 * kChunkLen);
4254 if (enable_partial_write) {
4255 // If partial writes are allowed, the write will succeed partially.
4256 ASSERT_EQ(ret, kChunkLen);
4257
4258 // Check the first half and make room for another record.
4259 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4260 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4261 count--;
4262
4263 // Finish writing the input.
4264 ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4265 kChunkLen);
4266 } else {
4267 // Otherwise, although the first half made it to the transport, the second
4268 // half is blocked.
4269 ASSERT_EQ(ret, -1);
4270 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_WRITE);
4271
4272 // Check the first half and make room for another record.
4273 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4274 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4275 count--;
4276
4277 // Retrying with fewer bytes than previously attempted is an error. If the
4278 // input length is less than the number of bytes successfully written, the
4279 // check happens at a different point, with a different error.
4280 //
4281 // TODO(davidben): Should these cases use the same error?
4282 ASSERT_EQ(
4283 SSL_get_error(client_.get(),
4284 SSL_write(client_.get(), data_longer, kChunkLen - 1)),
4285 SSL_ERROR_SSL);
4286 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_LENGTH));
4287
4288 // Complete the write with the correct retry.
4289 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4290 2 * kChunkLen);
4291 }
4292
4293 // Drain the input and ensure everything was written correctly.
4294 for (unsigned i = 0; i < count; i++) {
4295 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4296 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4297 }
4298
4299 // The final write is spread over two records.
4300 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4301 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4302 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4303 ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05004304 }
David Benjamin48063c22017-01-01 23:56:36 -05004305}
4306
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004307TEST_P(SSLVersionTest, RecordCallback) {
4308 for (bool test_server : {true, false}) {
4309 SCOPED_TRACE(test_server);
David Benjaminf7d37fb2023-02-04 19:45:04 -05004310 ASSERT_NO_FATAL_FAILURE(ResetContexts());
David Benjamin5df5be1a2017-06-22 19:43:11 -04004311
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004312 bool read_seen = false;
4313 bool write_seen = false;
4314 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
4315 size_t len, SSL *ssl) {
4316 if (cb_type != SSL3_RT_HEADER) {
4317 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004318 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004319
4320 // The callback does not report a version for records.
4321 EXPECT_EQ(0, cb_version);
4322
4323 if (is_write) {
4324 write_seen = true;
4325 } else {
4326 read_seen = true;
4327 }
4328
4329 // Sanity-check that the record header is plausible.
4330 CBS cbs;
4331 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
4332 uint8_t type;
4333 uint16_t record_version, length;
4334 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
4335 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05004336 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004337 if (is_dtls()) {
4338 uint16_t epoch;
4339 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
4340 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
4341 ASSERT_TRUE(CBS_skip(&cbs, 6));
4342 }
4343 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
4344 EXPECT_EQ(0u, CBS_len(&cbs));
4345 };
4346 using CallbackType = decltype(cb);
4347 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
4348 SSL_CTX_set_msg_callback(
4349 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
4350 size_t len, SSL *ssl, void *arg) {
4351 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
4352 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
4353 });
4354 SSL_CTX_set_msg_callback_arg(ctx, &cb);
4355
4356 ASSERT_TRUE(Connect());
4357
4358 EXPECT_TRUE(read_seen);
4359 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09004360 }
David Benjamin9ef31f02016-10-31 18:01:13 -04004361}
4362
David Benjamina8614602017-09-06 15:40:19 -04004363TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04004364 ClientConfig config;
4365 config.servername = "host1";
4366
4367 SSL_CTX_set_tlsext_servername_callback(
4368 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
4369 // During the handshake, |SSL_get_servername| must match |config|.
4370 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
4371 EXPECT_STREQ(config_p->servername.c_str(),
4372 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
4373 return SSL_TLSEXT_ERR_OK;
4374 });
4375 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
4376
4377 ASSERT_TRUE(Connect(config));
4378 // After the handshake, it must also be available.
4379 EXPECT_STREQ(config.servername.c_str(),
4380 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4381
4382 // Establish a session under host1.
4383 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4384 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4385 bssl::UniquePtr<SSL_SESSION> session =
4386 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
4387
4388 // If the client resumes a session with a different name, |SSL_get_servername|
4389 // must return the new name.
4390 ASSERT_TRUE(session);
4391 config.session = session.get();
4392 config.servername = "host2";
4393 ASSERT_TRUE(Connect(config));
4394 EXPECT_STREQ(config.servername.c_str(),
4395 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4396}
4397
David Benjamin3d8f0802017-09-06 16:12:52 -04004398// Test that session cache mode bits are honored in the client session callback.
4399TEST_P(SSLVersionTest, ClientSessionCacheMode) {
4400 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
4401 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4402
4403 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
4404 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4405
4406 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
4407 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4408}
4409
Steven Valdez777a2392019-02-21 11:30:47 -05004410// Test that all versions survive tiny write buffers. In particular, TLS 1.3
4411// NewSessionTickets are written post-handshake. Servers that block
4412// |SSL_do_handshake| on writing them will deadlock if clients are not draining
4413// the buffer. Test that we do not do this.
4414TEST_P(SSLVersionTest, SmallBuffer) {
4415 // DTLS is a datagram protocol and requires packet-sized buffers.
4416 if (is_dtls()) {
4417 return;
4418 }
4419
4420 // Test both flushing NewSessionTickets with a zero-sized write and
4421 // non-zero-sized write.
4422 for (bool use_zero_write : {false, true}) {
4423 SCOPED_TRACE(use_zero_write);
4424
4425 g_last_session = nullptr;
4426 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4427 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
4428
4429 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
4430 server(SSL_new(server_ctx_.get()));
4431 ASSERT_TRUE(client);
4432 ASSERT_TRUE(server);
4433 SSL_set_connect_state(client.get());
4434 SSL_set_accept_state(server.get());
4435
4436 // Use a tiny buffer.
4437 BIO *bio1, *bio2;
4438 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
4439
4440 // SSL_set_bio takes ownership.
4441 SSL_set_bio(client.get(), bio1, bio1);
4442 SSL_set_bio(server.get(), bio2, bio2);
4443
4444 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4445 if (version() >= TLS1_3_VERSION) {
4446 // The post-handshake ticket should not have been processed yet.
4447 EXPECT_FALSE(g_last_session);
4448 }
4449
4450 if (use_zero_write) {
4451 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
4452 EXPECT_TRUE(g_last_session);
4453 }
4454
4455 // Send some data from server to client. If |use_zero_write| is false, this
4456 // will also flush the NewSessionTickets.
4457 static const char kMessage[] = "hello world";
4458 char buf[sizeof(kMessage)];
4459 for (;;) {
4460 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
4461 int server_err = SSL_get_error(server.get(), server_ret);
4462 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
4463 int client_err = SSL_get_error(client.get(), client_ret);
4464
4465 // The server will write a single record, so every iteration should see
4466 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
4467 // iteration, where both will complete.
4468 if (server_ret > 0) {
4469 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
4470 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
4471 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
4472 break;
4473 }
4474
4475 ASSERT_EQ(server_ret, -1);
4476 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
4477 ASSERT_EQ(client_ret, -1);
4478 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4479 }
4480
4481 // The NewSessionTickets should have been flushed and processed.
4482 EXPECT_TRUE(g_last_session);
4483 }
4484}
4485
Adam Langleye1e78132017-01-31 15:24:31 -08004486TEST(SSLTest, AddChainCertHack) {
4487 // Ensure that we don't accidently break the hack that we have in place to
4488 // keep curl and serf happy when they use an |X509| even after transfering
4489 // ownership.
4490
4491 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4492 ASSERT_TRUE(ctx);
4493 X509 *cert = GetTestCertificate().release();
4494 ASSERT_TRUE(cert);
4495 SSL_CTX_add0_chain_cert(ctx.get(), cert);
4496
4497 // This should not trigger a use-after-free.
4498 X509_cmp(cert, cert);
4499}
4500
David Benjaminb2ff2622017-02-03 17:06:18 -05004501TEST(SSLTest, GetCertificate) {
4502 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4503 ASSERT_TRUE(ctx);
4504 bssl::UniquePtr<X509> cert = GetTestCertificate();
4505 ASSERT_TRUE(cert);
4506 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4507 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4508 ASSERT_TRUE(ssl);
4509
4510 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4511 ASSERT_TRUE(cert2);
4512 X509 *cert3 = SSL_get_certificate(ssl.get());
4513 ASSERT_TRUE(cert3);
4514
4515 // The old and new certificates must be identical.
4516 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4517 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
4518
4519 uint8_t *der = nullptr;
4520 long der_len = i2d_X509(cert.get(), &der);
4521 ASSERT_LT(0, der_len);
4522 bssl::UniquePtr<uint8_t> free_der(der);
4523
4524 uint8_t *der2 = nullptr;
4525 long der2_len = i2d_X509(cert2, &der2);
4526 ASSERT_LT(0, der2_len);
4527 bssl::UniquePtr<uint8_t> free_der2(der2);
4528
4529 uint8_t *der3 = nullptr;
4530 long der3_len = i2d_X509(cert3, &der3);
4531 ASSERT_LT(0, der3_len);
4532 bssl::UniquePtr<uint8_t> free_der3(der3);
4533
4534 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05004535 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4536 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05004537}
4538
Adam Langleyd04ca952017-02-28 11:26:51 -08004539TEST(SSLTest, SetChainAndKeyMismatch) {
4540 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4541 ASSERT_TRUE(ctx);
4542
4543 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4544 ASSERT_TRUE(key);
4545 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4546 ASSERT_TRUE(leaf);
4547 std::vector<CRYPTO_BUFFER*> chain = {
4548 leaf.get(),
4549 };
4550
4551 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004552 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), chain.data(), chain.size(),
Adam Langleyd04ca952017-02-28 11:26:51 -08004553 key.get(), nullptr));
4554 ERR_clear_error();
4555}
4556
David Benjamin5d880142024-02-20 17:34:14 -05004557TEST(SSLTest, CertThenKeyMismatch) {
4558 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4559 ASSERT_TRUE(ctx);
4560
4561 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4562 ASSERT_TRUE(key);
4563 bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
4564 ASSERT_TRUE(leaf);
4565
4566 // There is no key or certificate, so |SSL_CTX_check_private_key| fails.
4567 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4568
4569 // With only a certificate, |SSL_CTX_check_private_key| still fails.
4570 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4571 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4572
4573 // The private key does not match the certificate, so it should fail.
4574 EXPECT_FALSE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4575
4576 // Checking the private key fails, but this is really because there is still
4577 // no private key.
4578 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4579 EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
4580}
4581
4582TEST(SSLTest, KeyThenCertMismatch) {
4583 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4584 ASSERT_TRUE(ctx);
4585
4586 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4587 ASSERT_TRUE(key);
4588 bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
4589 ASSERT_TRUE(leaf);
4590
4591 // There is no key or certificate, so |SSL_CTX_check_private_key| fails.
4592 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4593
4594 // With only a key, |SSL_CTX_check_private_key| still fails.
4595 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4596 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4597
4598 // If configuring a certificate that doesn't match the key, configuration
4599 // actually succeeds. We just silently drop the private key.
4600 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4601 EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
4602
4603 // Some callers configure the private key, then the certificate, and then
4604 // expect |SSL_CTX_check_private_key| to check consistency. It does, but only
4605 // by way of noticing there is no private key. The actual consistency check
4606 // happened in |SSL_CTX_use_certificate|.
4607 EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4608}
4609
4610TEST(SSLTest, OverrideCertAndKey) {
4611 // It is possible to override an existing certificate by configuring
4612 // certificate, then key, due to |SSL_CTX_use_certificate|'s above silent
4613 // dropping behavior.
4614 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4615 ASSERT_TRUE(ctx);
4616
4617 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4618 ASSERT_TRUE(key);
4619 bssl::UniquePtr<X509> leaf = GetTestCertificate();
4620 ASSERT_TRUE(leaf);
4621 bssl::UniquePtr<EVP_PKEY> key2 = GetChainTestKey();
4622 ASSERT_TRUE(key2);
4623 bssl::UniquePtr<X509> leaf2 = GetChainTestCertificate();
4624 ASSERT_TRUE(leaf2);
4625
4626 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4627 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4628
4629 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf2.get()));
4630 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key2.get()));
4631}
4632
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004633TEST(SSLTest, SetChainAndKeyCtx) {
Adam Langleyd04ca952017-02-28 11:26:51 -08004634 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4635 ASSERT_TRUE(client_ctx);
4636 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4637 ASSERT_TRUE(server_ctx);
4638
Adam Langley964256d2020-03-19 11:57:12 -07004639 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4640
Adam Langleyd04ca952017-02-28 11:26:51 -08004641 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4642 ASSERT_TRUE(key);
4643 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4644 ASSERT_TRUE(leaf);
4645 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4646 GetChainTestIntermediateBuffer();
4647 ASSERT_TRUE(intermediate);
4648 std::vector<CRYPTO_BUFFER*> chain = {
4649 leaf.get(), intermediate.get(),
4650 };
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004651 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
Adam Langleyd04ca952017-02-28 11:26:51 -08004652 chain.size(), key.get(), nullptr));
4653
Adam Langley964256d2020-03-19 11:57:12 -07004654 ASSERT_EQ(chain.size(),
4655 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4656
David Benjamin3a1dd462017-07-11 16:13:10 -04004657 SSL_CTX_set_custom_verify(
4658 client_ctx.get(), SSL_VERIFY_PEER,
4659 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4660 return ssl_verify_ok;
4661 });
Adam Langleyd04ca952017-02-28 11:26:51 -08004662
4663 bssl::UniquePtr<SSL> client, server;
4664 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004665 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08004666}
4667
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004668TEST(SSLTest, SetChainAndKeySSL) {
4669 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4670 ASSERT_TRUE(client_ctx);
4671 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4672 ASSERT_TRUE(server_ctx);
4673
4674 bssl::UniquePtr<SSL> client, server;
4675 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4676 server_ctx.get()));
4677 SSL_set_shed_handshake_config(client.get(), true);
4678 SSL_set_shed_handshake_config(server.get(), true);
4679
4680 ASSERT_EQ(nullptr, SSL_get0_chain(server.get()));
4681
4682 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4683 ASSERT_TRUE(key);
4684 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4685 ASSERT_TRUE(leaf);
4686 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4687 GetChainTestIntermediateBuffer();
4688 ASSERT_TRUE(intermediate);
4689 std::vector<CRYPTO_BUFFER*> chain = {
4690 leaf.get(), intermediate.get(),
4691 };
4692 ASSERT_TRUE(SSL_set_chain_and_key(server.get(), chain.data(),
4693 chain.size(), key.get(), nullptr));
4694
4695 ASSERT_EQ(chain.size(),
4696 sk_CRYPTO_BUFFER_num(SSL_get0_chain(server.get())));
4697
4698 SSL_set_custom_verify(
4699 client.get(), SSL_VERIFY_PEER,
4700 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4701 return ssl_verify_ok;
4702 });
4703
4704 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4705
4706 // The server is configured to shed handshake config, so the certificate is no
4707 // longer available after the handshake.
4708 ASSERT_EQ(nullptr, SSL_get0_chain(server.get()));
4709}
4710
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004711TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4712 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4713 ASSERT_TRUE(client_ctx);
4714 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4715 ASSERT_TRUE(server_ctx);
4716
4717 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4718 ASSERT_TRUE(key);
4719 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4720 ASSERT_TRUE(leaf);
4721 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004722 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004723 chain.size(), key.get(), nullptr));
4724
4725 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4726 // configuration, certificate verification should fail.
4727 bssl::UniquePtr<SSL> client, server;
4728 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4729 server_ctx.get()));
4730
4731 // Whereas with a verifier, the connection should succeed.
4732 SSL_CTX_set_custom_verify(
4733 client_ctx.get(), SSL_VERIFY_PEER,
4734 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4735 return ssl_verify_ok;
4736 });
4737 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4738 server_ctx.get()));
4739}
4740
4741TEST(SSLTest, CustomVerify) {
4742 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4743 ASSERT_TRUE(client_ctx);
4744 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4745 ASSERT_TRUE(server_ctx);
4746
4747 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4748 ASSERT_TRUE(key);
4749 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4750 ASSERT_TRUE(leaf);
4751 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004752 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004753 chain.size(), key.get(), nullptr));
4754
4755 SSL_CTX_set_custom_verify(
4756 client_ctx.get(), SSL_VERIFY_PEER,
4757 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4758 return ssl_verify_ok;
4759 });
4760
4761 bssl::UniquePtr<SSL> client, server;
4762 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4763 server_ctx.get()));
4764
4765 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4766 // connection.
4767 SSL_CTX_set_custom_verify(
4768 client_ctx.get(), SSL_VERIFY_PEER,
4769 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4770 return ssl_verify_invalid;
4771 });
4772
4773 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4774 server_ctx.get()));
4775
4776 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4777 // connection.
4778 SSL_CTX_set_custom_verify(
4779 client_ctx.get(), SSL_VERIFY_NONE,
4780 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4781 return ssl_verify_invalid;
4782 });
4783
4784 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4785 server_ctx.get()));
4786}
4787
David Benjamin71dfad42017-07-16 17:27:39 -04004788TEST(SSLTest, ClientCABuffers) {
4789 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4790 ASSERT_TRUE(client_ctx);
4791 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4792 ASSERT_TRUE(server_ctx);
4793
4794 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4795 ASSERT_TRUE(key);
4796 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4797 ASSERT_TRUE(leaf);
4798 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4799 GetChainTestIntermediateBuffer();
4800 ASSERT_TRUE(intermediate);
4801 std::vector<CRYPTO_BUFFER *> chain = {
4802 leaf.get(),
4803 intermediate.get(),
4804 };
Gabriel Rednerfbb41332024-02-08 10:14:41 -05004805 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
David Benjamin71dfad42017-07-16 17:27:39 -04004806 chain.size(), key.get(), nullptr));
4807
4808 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4809 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4810 ASSERT_TRUE(ca_name);
4811 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4812 sk_CRYPTO_BUFFER_new_null());
4813 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04004814 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04004815 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
4816
4817 // Configure client and server to accept all certificates.
4818 SSL_CTX_set_custom_verify(
4819 client_ctx.get(), SSL_VERIFY_PEER,
4820 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4821 return ssl_verify_ok;
4822 });
4823 SSL_CTX_set_custom_verify(
4824 server_ctx.get(), SSL_VERIFY_PEER,
4825 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4826 return ssl_verify_ok;
4827 });
4828
4829 bool cert_cb_called = false;
4830 SSL_CTX_set_cert_cb(
4831 client_ctx.get(),
4832 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04004833 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04004834 SSL_get0_server_requested_CAs(ssl);
4835 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
4836 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
4837 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
4838 CRYPTO_BUFFER_len(peer_name)));
4839 *reinterpret_cast<bool *>(arg) = true;
4840 return 1;
4841 },
4842 &cert_cb_called);
4843
4844 bssl::UniquePtr<SSL> client, server;
4845 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004846 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04004847 EXPECT_TRUE(cert_cb_called);
4848}
4849
David Benjamin91222b82017-03-09 20:10:56 -05004850// Configuring the empty cipher list, though an error, should still modify the
4851// configuration.
4852TEST(SSLTest, EmptyCipherList) {
4853 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4854 ASSERT_TRUE(ctx);
4855
4856 // Initially, the cipher list is not empty.
4857 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4858
4859 // Configuring the empty cipher list fails.
4860 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4861 ERR_clear_error();
4862
4863 // But the cipher list is still updated to empty.
4864 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4865}
4866
Adam Langley4c341d02017-03-08 19:33:21 -08004867// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4868// test |SSL_TICKET_AEAD_METHOD| can fail.
4869enum ssl_test_ticket_aead_failure_mode {
4870 ssl_test_ticket_aead_ok = 0,
4871 ssl_test_ticket_aead_seal_fail,
4872 ssl_test_ticket_aead_open_soft_fail,
4873 ssl_test_ticket_aead_open_hard_fail,
4874};
4875
4876struct ssl_test_ticket_aead_state {
David Benjamindd68e4b2023-10-02 23:13:13 -04004877 unsigned retry_count = 0;
4878 ssl_test_ticket_aead_failure_mode failure_mode = ssl_test_ticket_aead_ok;
Adam Langley4c341d02017-03-08 19:33:21 -08004879};
4880
4881static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4882 const CRYPTO_EX_DATA *from,
4883 void **from_d, int index,
4884 long argl, void *argp) {
4885 abort();
4886}
4887
4888static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4889 CRYPTO_EX_DATA *ad, int index,
4890 long argl, void *argp) {
David Benjamindd68e4b2023-10-02 23:13:13 -04004891 delete reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
Adam Langley4c341d02017-03-08 19:33:21 -08004892}
4893
4894static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4895static int g_ssl_test_ticket_aead_ex_index;
4896
4897static int ssl_test_ticket_aead_get_ex_index() {
4898 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4899 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4900 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4901 ssl_test_ticket_aead_ex_index_free);
4902 });
4903 return g_ssl_test_ticket_aead_ex_index;
4904}
4905
4906static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4907 return 1;
4908}
4909
4910static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4911 size_t max_out_len, const uint8_t *in,
4912 size_t in_len) {
4913 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4914 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4915
4916 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4917 max_out_len < in_len + 1) {
4918 return 0;
4919 }
4920
4921 OPENSSL_memmove(out, in, in_len);
4922 out[in_len] = 0xff;
4923 *out_len = in_len + 1;
4924
4925 return 1;
4926}
4927
4928static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4929 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4930 const uint8_t *in, size_t in_len) {
4931 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4932 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4933
4934 if (state->retry_count > 0) {
4935 state->retry_count--;
4936 return ssl_ticket_aead_retry;
4937 }
4938
4939 switch (state->failure_mode) {
4940 case ssl_test_ticket_aead_ok:
4941 break;
4942 case ssl_test_ticket_aead_seal_fail:
4943 // If |seal| failed then there shouldn't be any ticket to try and
4944 // decrypt.
4945 abort();
4946 break;
4947 case ssl_test_ticket_aead_open_soft_fail:
4948 return ssl_ticket_aead_ignore_ticket;
4949 case ssl_test_ticket_aead_open_hard_fail:
4950 return ssl_ticket_aead_error;
4951 }
4952
4953 if (in_len == 0 || in[in_len - 1] != 0xff) {
4954 return ssl_ticket_aead_ignore_ticket;
4955 }
4956
4957 if (max_out_len < in_len - 1) {
4958 return ssl_ticket_aead_error;
4959 }
4960
4961 OPENSSL_memmove(out, in, in_len - 1);
4962 *out_len = in_len - 1;
4963 return ssl_ticket_aead_success;
4964}
4965
4966static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4967 ssl_test_ticket_aead_max_overhead,
4968 ssl_test_ticket_aead_seal,
4969 ssl_test_ticket_aead_open,
4970};
4971
4972static void ConnectClientAndServerWithTicketMethod(
4973 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4974 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4975 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4976 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4977 ASSERT_TRUE(client);
4978 ASSERT_TRUE(server);
4979 SSL_set_connect_state(client.get());
4980 SSL_set_accept_state(server.get());
4981
David Benjamindd68e4b2023-10-02 23:13:13 -04004982 auto state = new ssl_test_ticket_aead_state;
Adam Langley4c341d02017-03-08 19:33:21 -08004983 state->retry_count = retry_count;
4984 state->failure_mode = failure_mode;
4985
David Benjaminf7d37fb2023-02-04 19:45:04 -05004986 ASSERT_GE(ssl_test_ticket_aead_get_ex_index(), 0);
Adam Langley4c341d02017-03-08 19:33:21 -08004987 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4988 state));
4989
4990 SSL_set_session(client.get(), session);
4991
4992 BIO *bio1, *bio2;
4993 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4994
4995 // SSL_set_bio takes ownership.
4996 SSL_set_bio(client.get(), bio1, bio1);
4997 SSL_set_bio(server.get(), bio2, bio2);
4998
4999 if (CompleteHandshakes(client.get(), server.get())) {
5000 *out_client = std::move(client);
5001 *out_server = std::move(server);
5002 } else {
5003 out_client->reset();
5004 out_server->reset();
5005 }
5006}
5007
David Benjaminc9775322018-04-13 16:39:12 -04005008using TicketAEADMethodParam =
5009 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
5010
Adam Langley4c341d02017-03-08 19:33:21 -08005011class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04005012 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08005013
5014TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04005015 bssl::UniquePtr<SSL_CTX> server_ctx =
5016 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08005017 ASSERT_TRUE(server_ctx);
5018 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5019 ASSERT_TRUE(client_ctx);
5020
5021 const uint16_t version = testing::get<0>(GetParam());
5022 const unsigned retry_count = testing::get<1>(GetParam());
5023 const ssl_test_ticket_aead_failure_mode failure_mode =
5024 testing::get<2>(GetParam());
5025
Adam Langley4c341d02017-03-08 19:33:21 -08005026 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
5027 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
5028 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
5029 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
5030
5031 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
5032 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
5033 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
5034 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05005035 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08005036
5037 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
5038
5039 bssl::UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05005040 ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod(
5041 &client, &server, client_ctx.get(), server_ctx.get(), retry_count,
5042 failure_mode, nullptr));
Adam Langley4c341d02017-03-08 19:33:21 -08005043 switch (failure_mode) {
5044 case ssl_test_ticket_aead_ok:
5045 case ssl_test_ticket_aead_open_hard_fail:
5046 case ssl_test_ticket_aead_open_soft_fail:
5047 ASSERT_TRUE(client);
5048 break;
5049 case ssl_test_ticket_aead_seal_fail:
5050 EXPECT_FALSE(client);
5051 return;
5052 }
5053 EXPECT_FALSE(SSL_session_reused(client.get()));
5054 EXPECT_FALSE(SSL_session_reused(server.get()));
5055
Steven Valdez777a2392019-02-21 11:30:47 -05005056 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05005057 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
David Benjaminf7d37fb2023-02-04 19:45:04 -05005058 ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod(
5059 &client, &server, client_ctx.get(), server_ctx.get(), retry_count,
5060 failure_mode, session.get()));
Adam Langley4c341d02017-03-08 19:33:21 -08005061 switch (failure_mode) {
5062 case ssl_test_ticket_aead_ok:
5063 ASSERT_TRUE(client);
5064 EXPECT_TRUE(SSL_session_reused(client.get()));
5065 EXPECT_TRUE(SSL_session_reused(server.get()));
5066 break;
5067 case ssl_test_ticket_aead_seal_fail:
5068 abort();
5069 break;
5070 case ssl_test_ticket_aead_open_hard_fail:
5071 EXPECT_FALSE(client);
5072 break;
5073 case ssl_test_ticket_aead_open_soft_fail:
5074 ASSERT_TRUE(client);
5075 EXPECT_FALSE(SSL_session_reused(client.get()));
5076 EXPECT_FALSE(SSL_session_reused(server.get()));
5077 }
5078}
5079
David Benjaminc9775322018-04-13 16:39:12 -04005080std::string TicketAEADMethodParamToString(
5081 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
5082 std::string ret = GetVersionName(std::get<0>(params.param));
5083 // GTest only allows alphanumeric characters and '_' in the parameter
5084 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
5085 for (auto it = ret.begin(); it != ret.end();) {
5086 if (*it == '.' || *it == 'v') {
5087 it = ret.erase(it);
5088 } else {
5089 ++it;
5090 }
5091 }
5092 char retry_count[256];
David Benjamin4f1fae32021-12-15 11:41:10 -05005093 snprintf(retry_count, sizeof(retry_count), "%u", std::get<1>(params.param));
David Benjaminc9775322018-04-13 16:39:12 -04005094 ret += "_";
5095 ret += retry_count;
5096 ret += "Retries_";
5097 switch (std::get<2>(params.param)) {
5098 case ssl_test_ticket_aead_ok:
5099 ret += "OK";
5100 break;
5101 case ssl_test_ticket_aead_seal_fail:
5102 ret += "SealFail";
5103 break;
5104 case ssl_test_ticket_aead_open_soft_fail:
5105 ret += "OpenSoftFail";
5106 break;
5107 case ssl_test_ticket_aead_open_hard_fail:
5108 ret += "OpenHardFail";
5109 break;
5110 }
5111 return ret;
5112}
5113
David Benjaminbe7006a2019-04-09 18:05:02 -05005114INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08005115 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04005116 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
5117 testing::Values(0, 1, 2),
5118 testing::Values(ssl_test_ticket_aead_ok,
5119 ssl_test_ticket_aead_seal_fail,
5120 ssl_test_ticket_aead_open_soft_fail,
5121 ssl_test_ticket_aead_open_hard_fail)),
5122 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08005123
David Benjaminca743582017-06-15 17:51:35 -04005124TEST(SSLTest, SelectNextProto) {
5125 uint8_t *result;
5126 uint8_t result_len;
5127
5128 // If there is an overlap, it should be returned.
5129 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5130 SSL_select_next_proto(&result, &result_len,
5131 (const uint8_t *)"\1a\2bb\3ccc", 9,
5132 (const uint8_t *)"\1x\1y\1a\1z", 8));
5133 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
5134
5135 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5136 SSL_select_next_proto(&result, &result_len,
5137 (const uint8_t *)"\1a\2bb\3ccc", 9,
5138 (const uint8_t *)"\1x\1y\2bb\1z", 9));
5139 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
5140
5141 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5142 SSL_select_next_proto(&result, &result_len,
5143 (const uint8_t *)"\1a\2bb\3ccc", 9,
5144 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
5145 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
5146
5147 // Peer preference order takes precedence over local.
5148 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5149 SSL_select_next_proto(&result, &result_len,
5150 (const uint8_t *)"\1a\2bb\3ccc", 9,
5151 (const uint8_t *)"\3ccc\2bb\1a", 9));
5152 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
5153
5154 // If there is no overlap, return the first local protocol.
5155 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5156 SSL_select_next_proto(&result, &result_len,
5157 (const uint8_t *)"\1a\2bb\3ccc", 9,
5158 (const uint8_t *)"\1x\2yy\3zzz", 9));
5159 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
5160
5161 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5162 SSL_select_next_proto(&result, &result_len, nullptr, 0,
5163 (const uint8_t *)"\1x\2yy\3zzz", 9));
5164 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
5165}
5166
David Benjamin617b8182017-08-29 15:33:10 -04005167// The client should gracefully handle no suitable ciphers being enabled.
5168TEST(SSLTest, NoCiphersAvailable) {
5169 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5170 ASSERT_TRUE(ctx);
5171
5172 // Configure |client_ctx| with a cipher list that does not intersect with its
5173 // version configuration.
5174 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
5175 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
5176 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
5177
5178 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
5179 ASSERT_TRUE(ssl);
5180 SSL_set_connect_state(ssl.get());
5181
5182 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
5183 ASSERT_TRUE(rbio);
5184 ASSERT_TRUE(wbio);
5185 SSL_set0_rbio(ssl.get(), rbio.release());
5186 SSL_set0_wbio(ssl.get(), wbio.release());
5187
5188 int ret = SSL_do_handshake(ssl.get());
5189 EXPECT_EQ(-1, ret);
5190 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
David Benjaminec2a08d2024-02-21 23:21:16 -05005191 EXPECT_TRUE(
5192 ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE));
David Benjamin617b8182017-08-29 15:33:10 -04005193}
5194
David Benjamina4bafd32017-10-03 15:06:29 -04005195TEST_P(SSLVersionTest, SessionVersion) {
5196 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5197 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5198
5199 bssl::UniquePtr<SSL_SESSION> session =
5200 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5201 ASSERT_TRUE(session);
5202 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5203
5204 // Sessions in TLS 1.3 and later should be single-use.
5205 EXPECT_EQ(version() == TLS1_3_VERSION,
5206 !!SSL_SESSION_should_be_single_use(session.get()));
5207
5208 // Making fake sessions for testing works.
5209 session.reset(SSL_SESSION_new(client_ctx_.get()));
5210 ASSERT_TRUE(session);
5211 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
5212 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5213}
5214
David Benjaminfdb7a352017-10-12 17:34:18 -04005215TEST_P(SSLVersionTest, SSLPending) {
5216 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
5217 ASSERT_TRUE(ssl);
5218 EXPECT_EQ(0, SSL_pending(ssl.get()));
5219
5220 ASSERT_TRUE(Connect());
5221 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005222 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005223
5224 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
5225 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
5226 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005227 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005228
5229 char buf[10];
5230 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
5231 EXPECT_EQ(5, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005232 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005233
5234 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
5235 EXPECT_EQ(4, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005236 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005237
5238 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
5239 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005240 if (is_dtls()) {
5241 // In DTLS, the two records would have been read as a single datagram and
5242 // buffered inside |client_|. Thus, |SSL_has_pending| should return true.
5243 //
5244 // This test is slightly unrealistic. It relies on |ConnectClientAndServer|
5245 // using a |BIO| pair, which does not preserve datagram boundaries. Reading
5246 // 1 byte, then 4 bytes, from the first record also relies on
5247 // https://crbug.com/boringssl/65. But it does test the codepaths. When
5248 // fixing either of these bugs, this test may need to be redone.
5249 EXPECT_EQ(1, SSL_has_pending(client_.get()));
5250 } else {
5251 // In TLS, we do not overread, so |SSL_has_pending| should report no data is
5252 // buffered.
5253 EXPECT_EQ(0, SSL_has_pending(client_.get()));
5254 }
David Benjaminfdb7a352017-10-12 17:34:18 -04005255
5256 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
5257 EXPECT_EQ(3, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005258 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005259}
5260
David Benjamina031b612017-10-11 20:48:25 -04005261// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
5262TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04005263 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04005264 ASSERT_TRUE(ctx);
5265 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
5266 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
5267
David Benjamina031b612017-10-11 20:48:25 -04005268 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
5269
5270 bssl::UniquePtr<SSL> client, server;
5271 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
5272
5273 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
5274 ADD_FAILURE() << "New session callback called during SSL_shutdown";
5275 return 0;
5276 });
5277
5278 // Send close_notify.
5279 EXPECT_EQ(0, SSL_shutdown(server.get()));
5280 EXPECT_EQ(0, SSL_shutdown(client.get()));
5281
5282 // Receive close_notify.
5283 EXPECT_EQ(1, SSL_shutdown(server.get()));
5284 EXPECT_EQ(1, SSL_shutdown(client.get()));
5285}
5286
David Benjamin6cc352e2017-11-02 17:21:39 -04005287TEST(SSLTest, SignatureAlgorithmProperties) {
5288 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
5289 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
5290 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
5291
5292 EXPECT_EQ(EVP_PKEY_RSA,
5293 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5294 EXPECT_EQ(EVP_md5_sha1(),
5295 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5296 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5297
5298 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
5299 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5300 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
5301 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5302 EXPECT_FALSE(
5303 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
5304
5305 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04005306 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005307 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04005308 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5309 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005310}
5311
Adam Langley85967952018-07-03 08:04:58 -07005312static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
5313 size_t in_len) {
5314 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005315 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07005316 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005317 }
5318 }
5319
5320 SSL_set_app_data(ssl, XORCompressFunc);
5321
Adam Langley85967952018-07-03 08:04:58 -07005322 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005323}
5324
Adam Langley85967952018-07-03 08:04:58 -07005325static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
5326 size_t uncompressed_len, const uint8_t *in,
5327 size_t in_len) {
5328 if (in_len != uncompressed_len) {
5329 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005330 }
5331
5332 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07005333 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
5334 if (*out == nullptr) {
5335 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005336 }
5337
Adam Langley85967952018-07-03 08:04:58 -07005338 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005339 data[i] = in[i] ^ 0x55;
5340 }
5341
5342 SSL_set_app_data(ssl, XORDecompressFunc);
5343
Adam Langley85967952018-07-03 08:04:58 -07005344 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005345}
5346
5347TEST(SSLTest, CertCompression) {
5348 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005349 bssl::UniquePtr<SSL_CTX> server_ctx(
5350 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07005351 ASSERT_TRUE(client_ctx);
5352 ASSERT_TRUE(server_ctx);
5353
Adam Langley0080d832018-06-07 16:39:49 -07005354 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5355 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5356 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5357 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5358 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5359 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5360
5361 bssl::UniquePtr<SSL> client, server;
5362 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5363 server_ctx.get()));
5364
5365 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
5366 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
5367}
5368
Adam Langleyddb57cf2018-01-26 09:17:53 -08005369void MoveBIOs(SSL *dest, SSL *src) {
5370 BIO *rbio = SSL_get_rbio(src);
5371 BIO_up_ref(rbio);
5372 SSL_set0_rbio(dest, rbio);
5373
5374 BIO *wbio = SSL_get_wbio(src);
5375 BIO_up_ref(wbio);
5376 SSL_set0_wbio(dest, wbio);
5377
5378 SSL_set0_rbio(src, nullptr);
5379 SSL_set0_wbio(src, nullptr);
5380}
5381
Victor Tan3309ca62023-09-29 01:57:01 +00005382void VerifyHandoff(bool use_new_alps_codepoint) {
5383 static const uint8_t alpn[] = {0x03, 'f', 'o', 'o'};
5384 static const uint8_t proto[] = {'f', 'o', 'o'};
5385 static const uint8_t alps[] = {0x04, 'a', 'l', 'p', 's'};
5386
Adam Langleyddb57cf2018-01-26 09:17:53 -08005387 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5388 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005389 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
5390 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005391 ASSERT_TRUE(client_ctx);
5392 ASSERT_TRUE(server_ctx);
5393 ASSERT_TRUE(handshaker_ctx);
5394
Victor Tan3309ca62023-09-29 01:57:01 +00005395 if (!use_new_alps_codepoint) {
5396 SetUpExpectedOldCodePoint(server_ctx.get());
5397 } else {
5398 SetUpExpectedNewCodePoint(server_ctx.get());
5399 }
5400
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005401 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
5402 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005403 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005404 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05005405 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005406 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005407
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005408 for (bool early_data : {false, true}) {
5409 SCOPED_TRACE(early_data);
5410 for (bool is_resume : {false, true}) {
5411 SCOPED_TRACE(is_resume);
5412 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005413 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5414 server_ctx.get()));
5415 SSL_set_early_data_enabled(client.get(), early_data);
Victor Tan3309ca62023-09-29 01:57:01 +00005416
5417 // Set up client ALPS settings.
5418 SSL_set_alps_use_new_codepoint(client.get(), use_new_alps_codepoint);
5419 ASSERT_TRUE(SSL_set_alpn_protos(client.get(), alpn, sizeof(alpn)) == 0);
5420 ASSERT_TRUE(SSL_add_application_settings(client.get(), proto,
5421 sizeof(proto), nullptr, 0));
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005422 if (is_resume) {
5423 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04005424 SSL_set_session(client.get(), g_last_session.get());
5425 if (early_data) {
5426 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
5427 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005428 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04005429
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005430
5431 int client_ret = SSL_do_handshake(client.get());
5432 int client_err = SSL_get_error(client.get(), client_ret);
5433
5434 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005435 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005436 ASSERT_EQ(client_err, 0);
5437 EXPECT_TRUE(SSL_in_early_data(client.get()));
5438 // Attempt to write early data.
5439 byte_written = 43;
5440 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5441 } else {
5442 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5443 }
5444
5445 int server_ret = SSL_do_handshake(server.get());
5446 int server_err = SSL_get_error(server.get(), server_ret);
5447 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5448
5449 ScopedCBB cbb;
5450 Array<uint8_t> handoff;
5451 SSL_CLIENT_HELLO hello;
5452 ASSERT_TRUE(CBB_init(cbb.get(), 256));
5453 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5454 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5455
5456 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005457 ASSERT_TRUE(handshaker);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005458 // Note split handshakes determines 0-RTT support, for both the current
5459 // handshake and newly-issued tickets, entirely by |handshaker|. There is
5460 // no need to call |SSL_set_early_data_enabled| on |server|.
5461 SSL_set_early_data_enabled(handshaker.get(), 1);
Victor Tan3309ca62023-09-29 01:57:01 +00005462
5463 // Set up handshaker ALPS settings.
5464 SSL_set_alps_use_new_codepoint(handshaker.get(), use_new_alps_codepoint);
5465 SSL_CTX_set_alpn_select_cb(
5466 handshaker_ctx.get(),
5467 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5468 unsigned in_len, void *arg) -> int {
5469 return SSL_select_next_proto(
5470 const_cast<uint8_t **>(out), out_len, in, in_len,
5471 alpn, sizeof(alpn)) == OPENSSL_NPN_NEGOTIATED
5472 ? SSL_TLSEXT_ERR_OK
5473 : SSL_TLSEXT_ERR_NOACK;
5474 },
5475 nullptr);
5476 ASSERT_TRUE(SSL_add_application_settings(handshaker.get(), proto,
5477 sizeof(proto), alps, sizeof(alps)));
5478
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005479 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5480
5481 MoveBIOs(handshaker.get(), server.get());
5482
5483 int handshake_ret = SSL_do_handshake(handshaker.get());
5484 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5485 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5486
5487 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08005488 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005489 handshake_ret = SSL_do_handshake(handshaker.get());
5490 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5491 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5492
5493 ScopedCBB cbb_handback;
5494 Array<uint8_t> handback;
5495 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5496 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5497 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5498
5499 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005500 ASSERT_TRUE(server2);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005501 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5502
5503 MoveBIOs(server2.get(), handshaker.get());
5504 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5505 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
Victor Tan3309ca62023-09-29 01:57:01 +00005506 // Verify application settings.
5507 ASSERT_TRUE(SSL_has_application_settings(client.get()));
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005508
David Benjamin9b2cdb72021-04-01 23:21:53 -04005509 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005510 // In this case, one byte of early data has already been written above.
5511 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5512 } else {
5513 byte_written = 42;
5514 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5515 }
5516 uint8_t byte;
5517 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5518 EXPECT_EQ(byte_written, byte);
5519
5520 byte = 44;
5521 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5522 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5523 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005524 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005525 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08005526}
5527
Victor Tan3309ca62023-09-29 01:57:01 +00005528TEST(SSLTest, Handoff) {
5529 for (bool use_new_alps_codepoint : {false, true}) {
5530 SCOPED_TRACE(use_new_alps_codepoint);
5531 VerifyHandoff(use_new_alps_codepoint);
5532 }
5533}
5534
Adam Langleyddb57cf2018-01-26 09:17:53 -08005535TEST(SSLTest, HandoffDeclined) {
5536 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005537 bssl::UniquePtr<SSL_CTX> server_ctx(
5538 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005539 ASSERT_TRUE(client_ctx);
5540 ASSERT_TRUE(server_ctx);
5541
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005542 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Adam Langleyddb57cf2018-01-26 09:17:53 -08005543 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5544
Adam Langleyddb57cf2018-01-26 09:17:53 -08005545 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005546 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5547 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005548
5549 int client_ret = SSL_do_handshake(client.get());
5550 int client_err = SSL_get_error(client.get(), client_ret);
5551 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5552
5553 int server_ret = SSL_do_handshake(server.get());
5554 int server_err = SSL_get_error(server.get(), server_ret);
5555 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5556
5557 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005558 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005559 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005560 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005561
5562 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5563
5564 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5565
5566 uint8_t byte = 42;
5567 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5568 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5569 EXPECT_EQ(42, byte);
5570
5571 byte = 43;
5572 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5573 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5574 EXPECT_EQ(43, byte);
5575}
5576
Adam Langley826ce152018-08-03 10:31:21 -07005577static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5578 std::string ret = "{";
5579
5580 for (uint16_t v : sigalgs) {
5581 if (ret.size() > 1) {
5582 ret += ", ";
5583 }
5584
5585 char buf[8];
5586 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5587 buf[sizeof(buf)-1] = 0;
5588 ret += std::string(buf);
5589 }
5590
5591 ret += "}";
5592 return ret;
5593}
5594
5595void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5596 Span<const uint16_t> actual) {
5597 bool matches = false;
5598 if (expected.size() == actual.size()) {
5599 matches = true;
5600
5601 for (size_t i = 0; i < expected.size(); i++) {
5602 if (expected[i] != actual[i]) {
5603 matches = false;
5604 break;
5605 }
5606 }
5607 }
5608
5609 if (!matches) {
5610 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5611 << " got: " << SigAlgsToString(actual);
5612 }
5613}
5614
5615TEST(SSLTest, SigAlgs) {
5616 static const struct {
5617 std::vector<int> input;
5618 bool ok;
5619 std::vector<uint16_t> expected;
5620 } kTests[] = {
5621 {{}, true, {}},
5622 {{1}, false, {}},
5623 {{1, 2, 3}, false, {}},
5624 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5625 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5626
5627 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5628 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5629 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5630 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5631 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5632 true,
5633 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5634 };
5635
5636 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005637 ASSERT_TRUE(ctx);
Adam Langley826ce152018-08-03 10:31:21 -07005638
5639 unsigned n = 1;
5640 for (const auto &test : kTests) {
5641 SCOPED_TRACE(n++);
5642
5643 const bool ok =
5644 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5645 EXPECT_EQ(ok, test.ok);
5646
5647 if (!ok) {
5648 ERR_clear_error();
5649 }
5650
5651 if (!test.ok) {
5652 continue;
5653 }
5654
David Benjamin91a3f262024-02-10 11:08:08 -05005655 ExpectSigAlgsEqual(test.expected, ctx->cert->default_credential->sigalgs);
Adam Langley826ce152018-08-03 10:31:21 -07005656 }
5657}
5658
5659TEST(SSLTest, SigAlgsList) {
5660 static const struct {
5661 const char *input;
5662 bool ok;
5663 std::vector<uint16_t> expected;
5664 } kTests[] = {
5665 {"", false, {}},
5666 {":", false, {}},
5667 {"+", false, {}},
5668 {"RSA", false, {}},
5669 {"RSA+", false, {}},
5670 {"RSA+SHA256:", false, {}},
5671 {":RSA+SHA256:", false, {}},
5672 {":RSA+SHA256+:", false, {}},
5673 {"!", false, {}},
5674 {"\x01", false, {}},
5675 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5676 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5677
5678 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5679 {"RSA+SHA256:ed25519",
5680 true,
5681 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5682 {"ECDSA+SHA256:RSA+SHA512",
5683 true,
5684 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5685 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5686 true,
5687 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5688 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5689 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5690 };
5691
5692 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005693 ASSERT_TRUE(ctx);
Adam Langley826ce152018-08-03 10:31:21 -07005694
5695 unsigned n = 1;
5696 for (const auto &test : kTests) {
5697 SCOPED_TRACE(n++);
5698
5699 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5700 EXPECT_EQ(ok, test.ok);
5701
5702 if (!ok) {
5703 if (test.ok) {
5704 ERR_print_errors_fp(stderr);
5705 }
5706 ERR_clear_error();
5707 }
5708
5709 if (!test.ok) {
5710 continue;
5711 }
5712
David Benjamin91a3f262024-02-10 11:08:08 -05005713 ExpectSigAlgsEqual(test.expected, ctx->cert->default_credential->sigalgs);
Adam Langley826ce152018-08-03 10:31:21 -07005714 }
5715}
5716
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005717TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5718 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005719 ASSERT_TRUE(server_ctx);
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005720 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005721 ASSERT_TRUE(server);
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005722
5723 // handoff is a handoff message that has been artificially modified to pretend
David Benjaminb0251b12023-04-21 17:56:08 -04005724 // that only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) is supported. When
5725 // it is applied to |server|, all ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005726 //
5727 // To make a new one of these, try sticking this in the |Handoff| test above:
5728 //
5729 // hexdump(stderr, "", handoff.data(), handoff.size());
5730 // sed -e 's/\(..\)/0x\1, /g'
5731 //
5732 // and modify serialize_features() to emit only cipher 0x0A.
5733
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005734 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005735 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5736 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5737 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5738 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5739 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005740 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5741 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005742 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5743 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5744 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5745 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
David Benjaminb0251b12023-04-21 17:56:08 -04005746 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0xc0,
5747 0x2f, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005748 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005749 };
5750
David Benjaminb0251b12023-04-21 17:56:08 -04005751 EXPECT_LT(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005752 ASSERT_TRUE(
5753 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5754 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5755}
5756
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005757TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5758 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005759 ASSERT_TRUE(server_ctx);
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005760 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005761 ASSERT_TRUE(server);
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005762
5763 // handoff is a handoff message that has been artificially modified to pretend
David Benjamin2da5ba92023-05-26 21:23:39 -04005764 // that only one ECDH group is supported. When it is applied to |server|, all
5765 // groups but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005766 //
5767 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5768 // these.
5769 uint8_t handoff[] = {
5770 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5771 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5772 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5773 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5774 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5775 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5776 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5777 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5778 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5779 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5780 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5781 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5782 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5783 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5784 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5785 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5786 0x02, 0x00, 0x17,
5787 };
5788
5789 // The zero length means that the default list of groups is used.
5790 EXPECT_EQ(0u, server->config->supported_group_list.size());
5791 ASSERT_TRUE(
5792 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5793 EXPECT_EQ(1u, server->config->supported_group_list.size());
5794}
5795
Adam Langleyba9ad662018-12-17 13:59:38 -08005796TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5797 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5798 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005799 bssl::UniquePtr<SSL_CTX> server_ctx(
5800 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005801 ASSERT_TRUE(server_ctx);
Adam Langleyba9ad662018-12-17 13:59:38 -08005802 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5803 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005804
5805 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf7d37fb2023-02-04 19:45:04 -05005806 ASSERT_TRUE(client_ctx);
Adam Langleyba9ad662018-12-17 13:59:38 -08005807 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5808 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5809
5810 bssl::UniquePtr<SSL> client, server;
5811 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5812 server_ctx.get()));
5813
5814 BIO *client_wbio = SSL_get_wbio(client.get());
5815 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5816 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5817 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5818 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5819 EXPECT_NE(0u, BIO_wpending(client_wbio));
5820}
5821
David Benjamin5869eb32018-07-17 00:59:45 -04005822TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5823 // Configure the server to request client certificates.
5824 SSL_CTX_set_custom_verify(
5825 server_ctx_.get(), SSL_VERIFY_PEER,
5826 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5827
5828 // Configure the client to reject the server certificate.
5829 SSL_CTX_set_custom_verify(
5830 client_ctx_.get(), SSL_VERIFY_PEER,
5831 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5832
5833 // cert_cb should not be called. Verification should fail first.
5834 SSL_CTX_set_cert_cb(client_ctx_.get(),
5835 [](SSL *ssl, void *arg) {
5836 ADD_FAILURE() << "cert_cb unexpectedly called";
5837 return 0;
5838 },
5839 nullptr);
5840
5841 bssl::UniquePtr<SSL> client, server;
5842 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5843 server_ctx_.get()));
5844}
5845
David Benjamin492c9aa2018-08-31 16:35:22 -05005846// Test that ticket-based sessions on the client get fake session IDs.
5847TEST_P(SSLVersionTest, FakeIDsForTickets) {
5848 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5849 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5850
5851 bssl::UniquePtr<SSL_SESSION> session =
5852 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5853 ASSERT_TRUE(session);
5854
5855 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5856 unsigned session_id_length;
5857 SSL_SESSION_get_id(session.get(), &session_id_length);
5858 EXPECT_NE(session_id_length, 0u);
5859}
5860
David Benjamin6c04bd12018-07-19 18:13:09 -04005861// These tests test multi-threaded behavior. They are intended to run with
5862// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005863#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005864TEST_P(SSLVersionTest, SessionCacheThreads) {
5865 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5866 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5867 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5868
5869 if (version() == TLS1_3_VERSION) {
5870 // Our TLS 1.3 implementation does not support stateful resumption.
5871 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5872 return;
5873 }
5874
5875 // Establish two client sessions to test with.
5876 bssl::UniquePtr<SSL_SESSION> session1 =
5877 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5878 ASSERT_TRUE(session1);
5879 bssl::UniquePtr<SSL_SESSION> session2 =
5880 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5881 ASSERT_TRUE(session2);
5882
5883 auto connect_with_session = [&](SSL_SESSION *session) {
5884 ClientConfig config;
5885 config.session = session;
5886 UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05005887 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
David Benjamin6c04bd12018-07-19 18:13:09 -04005888 server_ctx_.get(), config));
5889 };
5890
5891 // Resume sessions in parallel with establishing new ones.
5892 {
5893 std::vector<std::thread> threads;
5894 threads.emplace_back([&] { connect_with_session(nullptr); });
5895 threads.emplace_back([&] { connect_with_session(nullptr); });
5896 threads.emplace_back([&] { connect_with_session(session1.get()); });
5897 threads.emplace_back([&] { connect_with_session(session1.get()); });
5898 threads.emplace_back([&] { connect_with_session(session2.get()); });
5899 threads.emplace_back([&] { connect_with_session(session2.get()); });
5900 for (auto &thread : threads) {
5901 thread.join();
5902 }
5903 }
5904
David Benjamina10017c2021-06-16 16:00:13 -04005905 // Hit the maximum session cache size across multiple threads, to test the
5906 // size enforcement logic.
David Benjamin6c04bd12018-07-19 18:13:09 -04005907 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5908 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5909 {
5910 std::vector<std::thread> threads;
5911 for (int i = 0; i < 4; i++) {
5912 threads.emplace_back([&]() {
5913 connect_with_session(nullptr);
5914 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5915 });
5916 }
5917 for (auto &thread : threads) {
5918 thread.join();
5919 }
5920 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5921 }
David Benjamina10017c2021-06-16 16:00:13 -04005922
5923 // Reset the session cache, this time with a mock clock.
5924 ASSERT_NO_FATAL_FAILURE(ResetContexts());
5925 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5926 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5927 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5928 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
5929
5930 // Make some sessions at an arbitrary start time. Then expire them.
5931 g_current_time.tv_sec = 1000;
5932 bssl::UniquePtr<SSL_SESSION> expired_session1 =
5933 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5934 ASSERT_TRUE(expired_session1);
5935 bssl::UniquePtr<SSL_SESSION> expired_session2 =
5936 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5937 ASSERT_TRUE(expired_session2);
5938 g_current_time.tv_sec += 100 * SSL_DEFAULT_SESSION_TIMEOUT;
5939
5940 session1 = CreateClientSession(client_ctx_.get(), server_ctx_.get());
5941 ASSERT_TRUE(session1);
5942
5943 // Every 256 connections, we flush stale sessions from the session cache. Test
5944 // this logic is correctly synchronized with other connection attempts.
5945 static const int kNumConnections = 256;
5946 {
5947 std::vector<std::thread> threads;
5948 threads.emplace_back([&] {
5949 for (int i = 0; i < kNumConnections; i++) {
5950 connect_with_session(nullptr);
5951 }
5952 });
5953 threads.emplace_back([&] {
5954 for (int i = 0; i < kNumConnections; i++) {
5955 connect_with_session(nullptr);
5956 }
5957 });
5958 threads.emplace_back([&] {
5959 // Never connect with |expired_session2|. The session cache eagerly
5960 // removes expired sessions when it sees them. Leaving |expired_session2|
5961 // untouched ensures it is instead cleared by periodic flushing.
5962 for (int i = 0; i < kNumConnections; i++) {
5963 connect_with_session(expired_session1.get());
5964 }
5965 });
5966 threads.emplace_back([&] {
5967 for (int i = 0; i < kNumConnections; i++) {
5968 connect_with_session(session1.get());
5969 }
5970 });
5971 for (auto &thread : threads) {
5972 thread.join();
5973 }
5974 }
David Benjamin6c04bd12018-07-19 18:13:09 -04005975}
5976
5977TEST_P(SSLVersionTest, SessionTicketThreads) {
5978 for (bool renew_ticket : {false, true}) {
5979 SCOPED_TRACE(renew_ticket);
David Benjaminf7d37fb2023-02-04 19:45:04 -05005980 ASSERT_NO_FATAL_FAILURE(ResetContexts());
David Benjamin6c04bd12018-07-19 18:13:09 -04005981 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5982 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5983 if (renew_ticket) {
5984 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5985 }
5986
5987 // Establish two client sessions to test with.
5988 bssl::UniquePtr<SSL_SESSION> session1 =
5989 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5990 ASSERT_TRUE(session1);
5991 bssl::UniquePtr<SSL_SESSION> session2 =
5992 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5993 ASSERT_TRUE(session2);
5994
5995 auto connect_with_session = [&](SSL_SESSION *session) {
5996 ClientConfig config;
5997 config.session = session;
5998 UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05005999 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
David Benjamin6c04bd12018-07-19 18:13:09 -04006000 server_ctx_.get(), config));
6001 };
6002
6003 // Resume sessions in parallel with establishing new ones.
6004 {
6005 std::vector<std::thread> threads;
6006 threads.emplace_back([&] { connect_with_session(nullptr); });
6007 threads.emplace_back([&] { connect_with_session(nullptr); });
6008 threads.emplace_back([&] { connect_with_session(session1.get()); });
6009 threads.emplace_back([&] { connect_with_session(session1.get()); });
6010 threads.emplace_back([&] { connect_with_session(session2.get()); });
6011 threads.emplace_back([&] { connect_with_session(session2.get()); });
6012 for (auto &thread : threads) {
6013 thread.join();
6014 }
6015 }
6016 }
6017}
6018
6019// SSL_CTX_get0_certificate needs to lock internally. Test this works.
6020TEST(SSLTest, GetCertificateThreads) {
6021 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6022 ASSERT_TRUE(ctx);
6023 bssl::UniquePtr<X509> cert = GetTestCertificate();
6024 ASSERT_TRUE(cert);
6025 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
6026
6027 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
6028 // threads concurrently. It originally was an immutable operation. Now we
6029 // implement it with a thread-safe cache, so it is worth testing.
6030 X509 *cert2_thread;
6031 std::thread thread(
6032 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
6033 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
6034 thread.join();
6035
David Benjaminf7d37fb2023-02-04 19:45:04 -05006036 ASSERT_TRUE(cert2);
6037 ASSERT_TRUE(cert2_thread);
David Benjamin6c04bd12018-07-19 18:13:09 -04006038 EXPECT_EQ(cert2, cert2_thread);
6039 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
6040}
David Benjamin4cce9552018-12-13 12:20:54 -06006041
6042// Functions which access properties on the negotiated session are thread-safe
6043// where needed. Prior to TLS 1.3, clients resuming sessions and servers
6044// performing stateful resumption will share an underlying SSL_SESSION object,
6045// potentially across threads.
6046TEST_P(SSLVersionTest, SessionPropertiesThreads) {
6047 if (version() == TLS1_3_VERSION) {
6048 // Our TLS 1.3 implementation does not support stateful resumption.
6049 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
6050 return;
6051 }
6052
6053 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
6054 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6055 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6056
6057 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
6058 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
6059
6060 // Configure mutual authentication, so we have more session state.
6061 SSL_CTX_set_custom_verify(
6062 client_ctx_.get(), SSL_VERIFY_PEER,
6063 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6064 SSL_CTX_set_custom_verify(
6065 server_ctx_.get(), SSL_VERIFY_PEER,
6066 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6067
6068 // Establish a client session to test with.
6069 bssl::UniquePtr<SSL_SESSION> session =
6070 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6071 ASSERT_TRUE(session);
6072
6073 // Resume with it twice.
6074 UniquePtr<SSL> ssls[4];
6075 ClientConfig config;
6076 config.session = session.get();
6077 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
6078 server_ctx_.get(), config));
6079 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
6080 server_ctx_.get(), config));
6081
6082 // Read properties in parallel.
6083 auto read_properties = [](const SSL *ssl) {
6084 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
6085 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
6086 EXPECT_TRUE(peer);
6087 EXPECT_TRUE(SSL_get_current_cipher(ssl));
David Benjamin335523a2023-05-26 21:55:56 -04006088 EXPECT_TRUE(SSL_get_group_id(ssl));
David Benjamin4cce9552018-12-13 12:20:54 -06006089 };
6090
6091 std::vector<std::thread> threads;
6092 for (const auto &ssl_ptr : ssls) {
6093 const SSL *ssl = ssl_ptr.get();
6094 threads.emplace_back([=] { read_properties(ssl); });
6095 }
6096 for (auto &thread : threads) {
6097 thread.join();
6098 }
6099}
David Benjamin2eaf0702023-05-13 10:22:35 -04006100
6101static void SetValueOnFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
6102 int index, long argl, void *argp) {
6103 if (ptr != nullptr) {
6104 *static_cast<long *>(ptr) = argl;
6105 }
6106}
6107
6108// Test that one thread can register ex_data while another thread is destroying
6109// an object that uses it.
6110TEST(SSLTest, ExDataThreads) {
6111 static bool already_run = false;
6112 if (already_run) {
6113 GTEST_SKIP() << "This test consumes process-global resources and can only "
6114 "be run once in a process. It is not compatible with "
6115 "--gtest_repeat.";
6116 }
6117 already_run = true;
6118
6119 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6120 ASSERT_TRUE(ctx);
6121
6122 // Register an initial index, so the threads can exercise having any ex_data.
6123 int first_index =
6124 SSL_get_ex_new_index(-1, nullptr, nullptr, nullptr, SetValueOnFree);
6125 ASSERT_GE(first_index, 0);
6126
6127 // Callers may register indices concurrently with using other indices. This
6128 // may happen if one part of an application is initializing while another part
6129 // is already running.
6130 static constexpr int kNumIndices = 3;
6131 static constexpr int kNumSSLs = 10;
6132 int index[kNumIndices];
6133 long values[kNumSSLs];
6134 std::fill(std::begin(values), std::end(values), -2);
6135 std::vector<std::thread> threads;
6136 for (size_t i = 0; i < kNumIndices; i++) {
6137 threads.emplace_back([&, i] {
6138 index[i] = SSL_get_ex_new_index(static_cast<long>(i), nullptr, nullptr,
6139 nullptr, SetValueOnFree);
6140 ASSERT_GE(index[i], 0);
6141 });
6142 }
6143 for (size_t i = 0; i < kNumSSLs; i++) {
6144 threads.emplace_back([&, i] {
6145 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
6146 ASSERT_TRUE(ssl);
6147 ASSERT_TRUE(SSL_set_ex_data(ssl.get(), first_index, &values[i]));
6148 });
6149 }
6150 for (auto &thread : threads) {
6151 thread.join();
6152 }
6153
6154 // Each of the SSL threads should have set their flag via ex_data.
6155 for (size_t i = 0; i < kNumSSLs; i++) {
6156 EXPECT_EQ(values[i], -1);
6157 }
6158
6159 // Each of the newly-registered indices should be distinct and work correctly.
6160 static_assert(kNumIndices <= kNumSSLs, "values buffer too small");
6161 std::fill(std::begin(values), std::end(values), -2);
6162 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
6163 ASSERT_TRUE(ssl);
6164 for (size_t i = 0; i < kNumIndices; i++) {
6165 for (size_t j = 0; j < i; j++) {
6166 EXPECT_NE(index[i], index[j]);
6167 }
6168 ASSERT_TRUE(SSL_set_ex_data(ssl.get(), index[i], &values[i]));
6169 }
6170 ssl = nullptr;
6171 for (size_t i = 0; i < kNumIndices; i++) {
6172 EXPECT_EQ(values[i], static_cast<long>(i));
6173 }
6174}
David Benjamina486c6c2019-03-28 18:32:38 -05006175#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04006176
Steven Valdezc8e0f902018-07-14 11:23:01 -04006177constexpr size_t kNumQUICLevels = 4;
6178static_assert(ssl_encryption_initial < kNumQUICLevels,
6179 "kNumQUICLevels is wrong");
6180static_assert(ssl_encryption_early_data < kNumQUICLevels,
6181 "kNumQUICLevels is wrong");
6182static_assert(ssl_encryption_handshake < kNumQUICLevels,
6183 "kNumQUICLevels is wrong");
6184static_assert(ssl_encryption_application < kNumQUICLevels,
6185 "kNumQUICLevels is wrong");
6186
David Benjamin1e859052020-02-09 16:04:58 -05006187const char *LevelToString(ssl_encryption_level_t level) {
6188 switch (level) {
6189 case ssl_encryption_initial:
6190 return "initial";
6191 case ssl_encryption_early_data:
6192 return "early data";
6193 case ssl_encryption_handshake:
6194 return "handshake";
6195 case ssl_encryption_application:
6196 return "application";
6197 }
6198 return "<unknown>";
6199}
6200
Steven Valdezc8e0f902018-07-14 11:23:01 -04006201class MockQUICTransport {
6202 public:
David Benjamind6343572019-08-15 17:29:02 -04006203 enum class Role { kClient, kServer };
6204
6205 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006206 // The caller is expected to configure initial secrets.
6207 levels_[ssl_encryption_initial].write_secret = {1};
6208 levels_[ssl_encryption_initial].read_secret = {1};
6209 }
6210
6211 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
6212
6213 bool has_alert() const { return has_alert_; }
6214 ssl_encryption_level_t alert_level() const { return alert_level_; }
6215 uint8_t alert() const { return alert_; }
6216
6217 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
6218 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05006219 levels_[level].read_secret == peer_->levels_[level].write_secret &&
6220 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006221 }
6222
David Benjamin1e859052020-02-09 16:04:58 -05006223 bool HasReadSecret(ssl_encryption_level_t level) const {
6224 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006225 }
6226
David Benjamin1e859052020-02-09 16:04:58 -05006227 bool HasWriteSecret(ssl_encryption_level_t level) const {
6228 return !levels_[level].write_secret.empty();
6229 }
6230
David Benjamin5298ef92020-03-13 12:17:30 -04006231 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
6232
David Benjamin1e859052020-02-09 16:04:58 -05006233 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
6234 Span<const uint8_t> secret) {
6235 if (HasReadSecret(level)) {
6236 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
6237 return false;
6238 }
6239
6240 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
6241 ADD_FAILURE() << "Unexpected early data read secret";
6242 return false;
6243 }
6244
6245 ssl_encryption_level_t ack_level =
6246 level == ssl_encryption_early_data ? ssl_encryption_application : level;
6247 if (!HasWriteSecret(ack_level)) {
6248 ADD_FAILURE() << LevelToString(level)
6249 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04006250 return false;
6251 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05006252
6253 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05006254 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05006255 return false;
6256 }
6257
David Benjamin1e859052020-02-09 16:04:58 -05006258 if (level != ssl_encryption_early_data &&
6259 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
6260 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04006261 return false;
6262 }
David Benjamind6343572019-08-15 17:29:02 -04006263
David Benjamin1e859052020-02-09 16:04:58 -05006264 levels_[level].read_secret.assign(secret.begin(), secret.end());
6265 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
6266 return true;
6267 }
6268
6269 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
6270 Span<const uint8_t> secret) {
6271 if (HasWriteSecret(level)) {
6272 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04006273 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006274 }
David Benjamind6343572019-08-15 17:29:02 -04006275
David Benjamin1e859052020-02-09 16:04:58 -05006276 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
6277 ADD_FAILURE() << "Unexpected early data write secret";
6278 return false;
6279 }
6280
6281 if (cipher == nullptr) {
6282 ADD_FAILURE() << "Unexpected null cipher";
6283 return false;
6284 }
6285
6286 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05006287 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006288 return true;
6289 }
6290
6291 bool WriteHandshakeData(ssl_encryption_level_t level,
6292 Span<const uint8_t> data) {
6293 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05006294 ADD_FAILURE() << LevelToString(level)
6295 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04006296 return false;
6297 }
David Benjamin5298ef92020-03-13 12:17:30 -04006298
6299 // Although the levels are conceptually separate, BoringSSL finishes writing
6300 // data from a previous level before installing keys for the next level.
6301 if (!allow_out_of_order_writes_) {
6302 switch (level) {
6303 case ssl_encryption_early_data:
6304 ADD_FAILURE() << "unexpected handshake data at early data level";
6305 return false;
6306 case ssl_encryption_initial:
6307 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
6308 ADD_FAILURE()
6309 << LevelToString(level)
6310 << " handshake data written after handshake keys installed";
6311 return false;
6312 }
6313 OPENSSL_FALLTHROUGH;
6314 case ssl_encryption_handshake:
6315 if (!levels_[ssl_encryption_application].write_secret.empty()) {
6316 ADD_FAILURE()
6317 << LevelToString(level)
6318 << " handshake data written after application keys installed";
6319 return false;
6320 }
6321 OPENSSL_FALLTHROUGH;
6322 case ssl_encryption_application:
6323 break;
6324 }
6325 }
6326
Steven Valdezc8e0f902018-07-14 11:23:01 -04006327 levels_[level].write_data.insert(levels_[level].write_data.end(),
6328 data.begin(), data.end());
6329 return true;
6330 }
6331
6332 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
6333 if (has_alert_) {
6334 ADD_FAILURE() << "duplicate alert sent";
6335 return false;
6336 }
6337
6338 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05006339 ADD_FAILURE() << LevelToString(level)
6340 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04006341 return false;
6342 }
6343
6344 has_alert_ = true;
6345 alert_level_ = level;
6346 alert_ = alert_value;
6347 return true;
6348 }
6349
6350 bool ReadHandshakeData(std::vector<uint8_t> *out,
6351 ssl_encryption_level_t level,
6352 size_t num = std::numeric_limits<size_t>::max()) {
6353 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04006354 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006355 return false;
6356 }
6357 // The peer may not have configured any keys yet.
6358 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04006359 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006360 return true;
6361 }
6362 // Check the peer computed the same key.
6363 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04006364 ADD_FAILURE() << "peer write key does not match read key in level "
6365 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006366 return false;
6367 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05006368 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04006369 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05006370 return false;
6371 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006372 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
6373 num = std::min(num, peer_data->size());
6374 out->assign(peer_data->begin(), peer_data->begin() + num);
6375 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
6376 return true;
6377 }
6378
6379 private:
David Benjamind6343572019-08-15 17:29:02 -04006380 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006381 MockQUICTransport *peer_ = nullptr;
6382
David Benjamin5298ef92020-03-13 12:17:30 -04006383 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006384 bool has_alert_ = false;
6385 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
6386 uint8_t alert_ = 0;
6387
6388 struct Level {
6389 std::vector<uint8_t> write_data;
6390 std::vector<uint8_t> write_secret;
6391 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05006392 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006393 };
6394 Level levels_[kNumQUICLevels];
6395};
6396
6397class MockQUICTransportPair {
6398 public:
David Benjamind6343572019-08-15 17:29:02 -04006399 MockQUICTransportPair()
6400 : client_(MockQUICTransport::Role::kClient),
6401 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006402 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04006403 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006404 }
6405
6406 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006407 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04006408 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006409 }
6410
6411 MockQUICTransport *client() { return &client_; }
6412 MockQUICTransport *server() { return &server_; }
6413
6414 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05006415 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
6416 // |PeerSecretsMatch| checks that |server_| is analogously configured.
6417 return client_.PeerSecretsMatch(level) &&
6418 client_.HasWriteSecret(level) &&
6419 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006420 }
6421
6422 private:
6423 MockQUICTransport client_;
6424 MockQUICTransport server_;
6425};
6426
6427class QUICMethodTest : public testing::Test {
6428 protected:
6429 void SetUp() override {
6430 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006431 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006432 ASSERT_TRUE(client_ctx_);
6433 ASSERT_TRUE(server_ctx_);
6434
Steven Valdezc8e0f902018-07-14 11:23:01 -04006435 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6436 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6437 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
6438 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07006439
6440 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
6441 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
6442 sizeof(kALPNProtos)),
6443 0);
6444 SSL_CTX_set_alpn_select_cb(
6445 server_ctx_.get(),
6446 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6447 unsigned in_len, void *arg) -> int {
6448 return SSL_select_next_proto(
6449 const_cast<uint8_t **>(out), out_len, in, in_len,
6450 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
6451 ? SSL_TLSEXT_ERR_OK
6452 : SSL_TLSEXT_ERR_NOACK;
6453 },
6454 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006455 }
6456
6457 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
6458 return ex_data_.Get(ssl);
6459 }
6460
6461 static bool ProvideHandshakeData(
6462 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
6463 MockQUICTransport *transport = TransportFromSSL(ssl);
6464 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
6465 std::vector<uint8_t> data;
6466 return transport->ReadHandshakeData(&data, level, num) &&
6467 SSL_provide_quic_data(ssl, level, data.data(), data.size());
6468 }
6469
David Benjamin5298ef92020-03-13 12:17:30 -04006470 void AllowOutOfOrderWrites() {
6471 allow_out_of_order_writes_ = true;
6472 }
6473
Steven Valdezc8e0f902018-07-14 11:23:01 -04006474 bool CreateClientAndServer() {
6475 client_.reset(SSL_new(client_ctx_.get()));
6476 server_.reset(SSL_new(server_ctx_.get()));
6477 if (!client_ || !server_) {
6478 return false;
6479 }
6480
6481 SSL_set_connect_state(client_.get());
6482 SSL_set_accept_state(server_.get());
6483
David Benjamina36ac0a2023-07-04 12:48:02 -04006484 transport_ = std::make_unique<MockQUICTransportPair>();
David Benjaminf7d37fb2023-02-04 19:45:04 -05006485 if (!ex_data_.Set(client_.get(), transport_->client()) ||
6486 !ex_data_.Set(server_.get(), transport_->server())) {
6487 return false;
6488 }
David Benjamin5298ef92020-03-13 12:17:30 -04006489 if (allow_out_of_order_writes_) {
6490 transport_->client()->AllowOutOfOrderWrites();
6491 transport_->server()->AllowOutOfOrderWrites();
6492 }
Nick Harper7c522992020-04-30 14:15:49 -07006493 static const uint8_t client_transport_params[] = {0};
6494 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
6495 sizeof(client_transport_params)) ||
6496 !SSL_set_quic_transport_params(server_.get(),
6497 server_transport_params_.data(),
6498 server_transport_params_.size()) ||
6499 !SSL_set_quic_early_data_context(
6500 server_.get(), server_quic_early_data_context_.data(),
6501 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07006502 return false;
6503 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006504 return true;
6505 }
6506
Nick Harper72cff812020-03-26 18:06:16 -07006507 enum class ExpectedError {
6508 kNoError,
6509 kClientError,
6510 kServerError,
6511 };
6512
David Benjamind6343572019-08-15 17:29:02 -04006513 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
6514 // |server_| until each completes once. It returns true on success and false
6515 // on failure.
6516 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07006517 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
6518 }
6519
6520 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
6521 // once. If |expect_client_error| is true, it will return true only if the
6522 // client handshake failed. Otherwise, it returns true if both handshakes
6523 // succeed and false otherwise.
6524 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04006525 bool client_done = false, server_done = false;
6526 while (!client_done || !server_done) {
6527 if (!client_done) {
6528 if (!ProvideHandshakeData(client_.get())) {
6529 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
6530 return false;
6531 }
6532 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006533 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04006534 if (client_ret == 1) {
6535 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006536 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006537 if (expected_error == ExpectedError::kClientError) {
6538 return true;
6539 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006540 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
6541 << client_err;
6542 return false;
David Benjamind6343572019-08-15 17:29:02 -04006543 }
6544 }
6545
6546 if (!server_done) {
6547 if (!ProvideHandshakeData(server_.get())) {
6548 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
6549 return false;
6550 }
6551 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006552 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04006553 if (server_ret == 1) {
6554 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006555 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006556 if (expected_error == ExpectedError::kServerError) {
6557 return true;
6558 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006559 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
6560 << server_err;
6561 return false;
David Benjamind6343572019-08-15 17:29:02 -04006562 }
6563 }
6564 }
Nick Harper72cff812020-03-26 18:06:16 -07006565 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04006566 }
6567
6568 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
6569 g_last_session = nullptr;
6570 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6571 if (!CreateClientAndServer() ||
6572 !CompleteHandshakesForQUIC()) {
6573 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006574 }
6575
David Benjamind6343572019-08-15 17:29:02 -04006576 // The server sent NewSessionTicket messages in the handshake.
6577 if (!ProvideHandshakeData(client_.get()) ||
6578 !SSL_process_quic_post_handshake(client_.get())) {
6579 return nullptr;
6580 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006581
David Benjamind6343572019-08-15 17:29:02 -04006582 return std::move(g_last_session);
6583 }
6584
6585 void ExpectHandshakeSuccess() {
6586 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6587 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
6588 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
6589 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
6590 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
6591 EXPECT_FALSE(transport_->client()->has_alert());
6592 EXPECT_FALSE(transport_->server()->has_alert());
6593
6594 // SSL_do_handshake is now idempotent.
6595 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6596 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006597 }
6598
David Benjamin1e859052020-02-09 16:04:58 -05006599 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
6600 // the test.
6601 SSL_QUIC_METHOD DefaultQUICMethod() {
6602 return SSL_QUIC_METHOD{
6603 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
6604 FlushFlightCallback, SendAlertCallback,
6605 };
6606 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006607
David Benjamin1e859052020-02-09 16:04:58 -05006608 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6609 const SSL_CIPHER *cipher,
6610 const uint8_t *secret, size_t secret_len) {
6611 return TransportFromSSL(ssl)->SetReadSecret(
6612 level, cipher, MakeConstSpan(secret, secret_len));
6613 }
6614
6615 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6616 const SSL_CIPHER *cipher,
6617 const uint8_t *secret, size_t secret_len) {
6618 return TransportFromSSL(ssl)->SetWriteSecret(
6619 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006620 }
6621
David Benjamincc9d9352018-10-30 19:45:22 -05006622 static int AddHandshakeDataCallback(SSL *ssl,
6623 enum ssl_encryption_level_t level,
6624 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006625 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6626 return TransportFromSSL(ssl)->WriteHandshakeData(level,
6627 MakeConstSpan(data, len));
6628 }
6629
6630 static int FlushFlightCallback(SSL *ssl) { return 1; }
6631
6632 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6633 uint8_t alert) {
6634 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6635 return TransportFromSSL(ssl)->SendAlert(level, alert);
6636 }
6637
6638 bssl::UniquePtr<SSL_CTX> client_ctx_;
6639 bssl::UniquePtr<SSL_CTX> server_ctx_;
6640
6641 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04006642 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006643
6644 bssl::UniquePtr<SSL> client_;
6645 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04006646
Nick Harper7c522992020-04-30 14:15:49 -07006647 std::vector<uint8_t> server_transport_params_ = {1};
6648 std::vector<uint8_t> server_quic_early_data_context_ = {2};
6649
David Benjamin5298ef92020-03-13 12:17:30 -04006650 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006651};
6652
6653UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6654
David Benjaminfd863b62019-07-25 13:51:32 -04006655// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006656TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05006657 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006658
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006659 g_last_session = nullptr;
6660
6661 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6662 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006663 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6664 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04006665
Steven Valdezc8e0f902018-07-14 11:23:01 -04006666 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006667 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006668
David Benjamind6343572019-08-15 17:29:02 -04006669 ExpectHandshakeSuccess();
6670 EXPECT_FALSE(SSL_session_reused(client_.get()));
6671 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006672
6673 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006674 EXPECT_FALSE(g_last_session);
6675 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6676 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6677 EXPECT_TRUE(g_last_session);
6678
6679 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04006680 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006681 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6682 SSL_set_session(client_.get(), session.get());
6683
David Benjamind6343572019-08-15 17:29:02 -04006684 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006685
David Benjamind6343572019-08-15 17:29:02 -04006686 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006687 EXPECT_TRUE(SSL_session_reused(client_.get()));
6688 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006689}
6690
David Benjaminfd863b62019-07-25 13:51:32 -04006691// Test that HelloRetryRequest in QUIC works.
6692TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006693 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006694
6695 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6696 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6697
David Benjamin2da5ba92023-05-26 21:23:39 -04006698 // BoringSSL predicts the most preferred ECDH group, so using different
6699 // preferences will trigger HelloRetryRequest.
David Benjaminfd863b62019-07-25 13:51:32 -04006700 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
David Benjamin2da5ba92023-05-26 21:23:39 -04006701 ASSERT_TRUE(SSL_CTX_set1_groups(client_ctx_.get(), kClientPrefs,
David Benjaminfd863b62019-07-25 13:51:32 -04006702 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6703 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
David Benjamin2da5ba92023-05-26 21:23:39 -04006704 ASSERT_TRUE(SSL_CTX_set1_groups(server_ctx_.get(), kServerPrefs,
David Benjaminfd863b62019-07-25 13:51:32 -04006705 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6706
6707 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006708 ASSERT_TRUE(CompleteHandshakesForQUIC());
6709 ExpectHandshakeSuccess();
6710}
David Benjaminfd863b62019-07-25 13:51:32 -04006711
Nick Harpere32549e2020-05-06 14:27:11 -07006712// Test that the client does not send a legacy_session_id in the ClientHello.
6713TEST_F(QUICMethodTest, NoLegacySessionId) {
6714 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6715
6716 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6717 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6718 // Check that the session ID length is 0 in an early callback.
6719 SSL_CTX_set_select_certificate_cb(
6720 server_ctx_.get(),
6721 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6722 EXPECT_EQ(client_hello->session_id_len, 0u);
6723 return ssl_select_cert_success;
6724 });
6725
6726 ASSERT_TRUE(CreateClientAndServer());
6727 ASSERT_TRUE(CompleteHandshakesForQUIC());
6728
6729 ExpectHandshakeSuccess();
6730}
6731
David Benjamin1e859052020-02-09 16:04:58 -05006732// Test that, even in a 1-RTT handshake, the server installs keys at the right
6733// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6734TEST_F(QUICMethodTest, HalfRTTKeys) {
6735 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6736
6737 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6738 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6739 ASSERT_TRUE(CreateClientAndServer());
6740
6741 // The client sends ClientHello.
6742 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6743 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6744
6745 // The server reads ClientHello and sends ServerHello..Finished.
6746 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6747 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6748 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6749
6750 // At this point, the server has half-RTT write keys, but it cannot access
6751 // 1-RTT read keys until client Finished.
6752 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6753 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6754
6755 // Finish up the client and server handshakes.
6756 ASSERT_TRUE(CompleteHandshakesForQUIC());
6757
6758 // Both sides can now exchange 1-RTT data.
6759 ExpectHandshakeSuccess();
6760}
6761
David Benjamind6343572019-08-15 17:29:02 -04006762TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006763 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006764
6765 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6766 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6767 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6768 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6769 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6770
6771 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6772 ASSERT_TRUE(session);
6773
6774 ASSERT_TRUE(CreateClientAndServer());
6775 SSL_set_session(client_.get(), session.get());
6776
6777 // The client handshake should return immediately into the early data state.
6778 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6779 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6780 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006781 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006782
6783 // The server will consume the ClientHello and also enter the early data
6784 // state.
6785 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6786 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6787 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6788 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006789 // At this point, the server has half-RTT write keys, but it cannot access
6790 // 1-RTT read keys until client Finished.
6791 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6792 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006793
6794 // Finish up the client and server handshakes.
6795 ASSERT_TRUE(CompleteHandshakesForQUIC());
6796
6797 // Both sides can now exchange 1-RTT data.
6798 ExpectHandshakeSuccess();
6799 EXPECT_TRUE(SSL_session_reused(client_.get()));
6800 EXPECT_TRUE(SSL_session_reused(server_.get()));
6801 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6802 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6803 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6804 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006805
6806 // Finish handling post-handshake messages after the first 0-RTT resumption.
6807 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6808 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6809
6810 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6811 // accepted again.
6812 ASSERT_TRUE(CreateClientAndServer());
6813 SSL_set_session(client_.get(), g_last_session.get());
6814
6815 // The client handshake should return immediately into the early data state.
6816 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6817 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6818 // The transport should have keys for sending 0-RTT data.
6819 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6820
6821 // The server will consume the ClientHello and also enter the early data
6822 // state.
6823 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6824 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6825 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6826 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6827 // At this point, the server has half-RTT write keys, but it cannot access
6828 // 1-RTT read keys until client Finished.
6829 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6830 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6831
6832 // Finish up the client and server handshakes.
6833 ASSERT_TRUE(CompleteHandshakesForQUIC());
6834
6835 // Both sides can now exchange 1-RTT data.
6836 ExpectHandshakeSuccess();
6837 EXPECT_TRUE(SSL_session_reused(client_.get()));
6838 EXPECT_TRUE(SSL_session_reused(server_.get()));
6839 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6840 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6841 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6842 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6843 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6844 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006845}
6846
Nick Harper7c522992020-04-30 14:15:49 -07006847TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6848 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6849
6850 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6851 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6852 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6853 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6854 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6855
6856
6857 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6858 ASSERT_TRUE(session);
6859
Nick Harper85194322020-05-20 16:59:29 -07006860 ASSERT_TRUE(CreateClientAndServer());
6861 static const uint8_t new_context[] = {4};
6862 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6863 sizeof(new_context)));
6864 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006865
Nick Harper85194322020-05-20 16:59:29 -07006866 // The client handshake should return immediately into the early data
6867 // state.
6868 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6869 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6870 // The transport should have keys for sending 0-RTT data.
6871 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006872
Nick Harper85194322020-05-20 16:59:29 -07006873 // The server will consume the ClientHello, but it will not accept 0-RTT.
6874 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6875 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
David Benjaminf7d37fb2023-02-04 19:45:04 -05006876 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
Nick Harper85194322020-05-20 16:59:29 -07006877 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6878 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006879
Nick Harper85194322020-05-20 16:59:29 -07006880 // The client consumes the server response and signals 0-RTT rejection.
6881 for (;;) {
6882 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6883 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6884 int err = SSL_get_error(client_.get(), -1);
6885 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6886 break;
Nick Harper7c522992020-04-30 14:15:49 -07006887 }
Nick Harper85194322020-05-20 16:59:29 -07006888 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006889 }
Nick Harper85194322020-05-20 16:59:29 -07006890
6891 // As in TLS over TCP, 0-RTT rejection is sticky.
6892 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6893 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6894
6895 // Finish up the client and server handshakes.
6896 SSL_reset_early_data_reject(client_.get());
6897 ASSERT_TRUE(CompleteHandshakesForQUIC());
6898
6899 // Both sides can now exchange 1-RTT data.
6900 ExpectHandshakeSuccess();
6901 EXPECT_TRUE(SSL_session_reused(client_.get()));
6902 EXPECT_TRUE(SSL_session_reused(server_.get()));
6903 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6904 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6905 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6906 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6907}
6908
6909TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6910 server_quic_early_data_context_ = {};
6911 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6912
6913 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6914 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6915 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6916 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6917 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6918
6919 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6920 ASSERT_TRUE(session);
6921 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006922}
6923
David Benjamind6343572019-08-15 17:29:02 -04006924TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006925 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006926
6927 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6928 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6929 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6930 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6931 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6932
6933 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6934 ASSERT_TRUE(session);
6935
6936 for (bool reject_hrr : {false, true}) {
6937 SCOPED_TRACE(reject_hrr);
6938
6939 ASSERT_TRUE(CreateClientAndServer());
6940 if (reject_hrr) {
6941 // Configure the server to prefer P-256, which will reject 0-RTT via
6942 // HelloRetryRequest.
6943 int p256 = NID_X9_62_prime256v1;
David Benjamin2da5ba92023-05-26 21:23:39 -04006944 ASSERT_TRUE(SSL_set1_groups(server_.get(), &p256, 1));
David Benjamind6343572019-08-15 17:29:02 -04006945 } else {
6946 // Disable 0-RTT on the server, so it will reject it.
6947 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006948 }
David Benjamind6343572019-08-15 17:29:02 -04006949 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006950
David Benjamind6343572019-08-15 17:29:02 -04006951 // The client handshake should return immediately into the early data state.
6952 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6953 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6954 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006955 EXPECT_TRUE(
6956 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006957
6958 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006959 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006960 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
David Benjaminf7d37fb2023-02-04 19:45:04 -05006961 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
David Benjamind6343572019-08-15 17:29:02 -04006962 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006963 EXPECT_FALSE(
6964 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006965
6966 // The client consumes the server response and signals 0-RTT rejection.
6967 for (;;) {
6968 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6969 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6970 int err = SSL_get_error(client_.get(), -1);
6971 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6972 break;
6973 }
6974 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006975 }
6976
David Benjamind6343572019-08-15 17:29:02 -04006977 // As in TLS over TCP, 0-RTT rejection is sticky.
6978 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6979 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6980
6981 // Finish up the client and server handshakes.
6982 SSL_reset_early_data_reject(client_.get());
6983 ASSERT_TRUE(CompleteHandshakesForQUIC());
6984
6985 // Both sides can now exchange 1-RTT data.
6986 ExpectHandshakeSuccess();
6987 EXPECT_TRUE(SSL_session_reused(client_.get()));
6988 EXPECT_TRUE(SSL_session_reused(server_.get()));
6989 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6990 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6991 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6992 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006993 }
David Benjaminfd863b62019-07-25 13:51:32 -04006994}
6995
David Benjaminee0716f2019-11-19 14:16:28 +08006996TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006997 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006998
6999 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7000 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
7001 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
7002 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
7003 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7004 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7005
7006 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
7007 ASSERT_TRUE(session);
7008
7009 ASSERT_TRUE(CreateClientAndServer());
7010 SSL_set_session(client_.get(), session.get());
7011
7012 // Configure the certificate (re)verification to never complete. The client
7013 // handshake should pause.
7014 SSL_set_custom_verify(
7015 client_.get(), SSL_VERIFY_PEER,
7016 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7017 return ssl_verify_retry;
7018 });
7019 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7020 ASSERT_EQ(SSL_get_error(client_.get(), -1),
7021 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
7022
7023 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05007024 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08007025
7026 // After the verification completes, the handshake progresses to the 0-RTT
7027 // point and releases keys.
7028 SSL_set_custom_verify(
7029 client_.get(), SSL_VERIFY_PEER,
7030 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7031 return ssl_verify_ok;
7032 });
7033 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
7034 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05007035 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08007036}
7037
Steven Valdezc8e0f902018-07-14 11:23:01 -04007038// Test only releasing data to QUIC one byte at a time on request, to maximize
7039// state machine pauses. Additionally, test that existing asynchronous callbacks
7040// still work.
7041TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05007042 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04007043
7044 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7045 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7046 ASSERT_TRUE(CreateClientAndServer());
7047
7048 // Install an asynchronous certificate callback.
7049 bool cert_cb_ok = false;
7050 SSL_set_cert_cb(server_.get(),
7051 [](SSL *, void *arg) -> int {
7052 return *static_cast<bool *>(arg) ? 1 : -1;
7053 },
7054 &cert_cb_ok);
7055
7056 for (;;) {
7057 int client_ret = SSL_do_handshake(client_.get());
7058 if (client_ret != 1) {
7059 ASSERT_EQ(client_ret, -1);
7060 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
7061 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
7062 }
7063
7064 int server_ret = SSL_do_handshake(server_.get());
7065 if (server_ret != 1) {
7066 ASSERT_EQ(server_ret, -1);
7067 int ssl_err = SSL_get_error(server_.get(), server_ret);
7068 switch (ssl_err) {
7069 case SSL_ERROR_WANT_READ:
7070 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
7071 break;
7072 case SSL_ERROR_WANT_X509_LOOKUP:
7073 ASSERT_FALSE(cert_cb_ok);
7074 cert_cb_ok = true;
7075 break;
7076 default:
7077 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
7078 }
7079 }
7080
7081 if (client_ret == 1 && server_ret == 1) {
7082 break;
7083 }
7084 }
7085
David Benjamind6343572019-08-15 17:29:02 -04007086 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04007087}
7088
7089// Test buffering write data until explicit flushes.
7090TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04007091 AllowOutOfOrderWrites();
7092
Steven Valdezc8e0f902018-07-14 11:23:01 -04007093 struct BufferedFlight {
7094 std::vector<uint8_t> data[kNumQUICLevels];
7095 };
7096 static UnownedSSLExData<BufferedFlight> buffered_flights;
7097
David Benjamincc9d9352018-10-30 19:45:22 -05007098 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
7099 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04007100 BufferedFlight *flight = buffered_flights.Get(ssl);
7101 flight->data[level].insert(flight->data[level].end(), data, data + len);
7102 return 1;
7103 };
7104
7105 auto flush_flight = [](SSL *ssl) -> int {
7106 BufferedFlight *flight = buffered_flights.Get(ssl);
7107 for (size_t level = 0; level < kNumQUICLevels; level++) {
7108 if (!flight->data[level].empty()) {
7109 if (!TransportFromSSL(ssl)->WriteHandshakeData(
7110 static_cast<ssl_encryption_level_t>(level),
7111 flight->data[level])) {
7112 return 0;
7113 }
7114 flight->data[level].clear();
7115 }
7116 }
7117 return 1;
7118 };
7119
David Benjamin1e859052020-02-09 16:04:58 -05007120 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7121 quic_method.add_handshake_data = add_handshake_data;
7122 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04007123
7124 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7125 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7126 ASSERT_TRUE(CreateClientAndServer());
7127
7128 BufferedFlight client_flight, server_flight;
David Benjaminf7d37fb2023-02-04 19:45:04 -05007129 ASSERT_TRUE(buffered_flights.Set(client_.get(), &client_flight));
7130 ASSERT_TRUE(buffered_flights.Set(server_.get(), &server_flight));
Steven Valdezc8e0f902018-07-14 11:23:01 -04007131
David Benjamind6343572019-08-15 17:29:02 -04007132 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04007133
David Benjamind6343572019-08-15 17:29:02 -04007134 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04007135}
7136
7137// Test that excess data at one level is rejected. That is, if a single
7138// |SSL_provide_quic_data| call included both ServerHello and
7139// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
7140// key change.
7141TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04007142 AllowOutOfOrderWrites();
7143
David Benjamincc9d9352018-10-30 19:45:22 -05007144 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
7145 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04007146 // Switch everything to the initial level.
7147 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
7148 MakeConstSpan(data, len));
7149 };
7150
David Benjamin1e859052020-02-09 16:04:58 -05007151 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7152 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04007153
7154 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7155 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7156 ASSERT_TRUE(CreateClientAndServer());
7157
7158 // Send the ClientHello and ServerHello through Finished.
7159 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7160 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7161 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7162 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7163 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
7164
7165 // The client is still waiting for the ServerHello at initial
7166 // encryption.
7167 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
7168
David Benjamincc9d9352018-10-30 19:45:22 -05007169 // |add_handshake_data| incorrectly wrote everything at the initial level, so
7170 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04007171 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7172
7173 // The client reads ServerHello successfully, but then rejects the buffered
7174 // EncryptedExtensions on key change.
7175 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7176 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
David Benjaminec2a08d2024-02-21 23:21:16 -05007177 EXPECT_TRUE(
7178 ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_EXCESS_HANDSHAKE_DATA));
Steven Valdezc8e0f902018-07-14 11:23:01 -04007179
David Benjamin1e859052020-02-09 16:04:58 -05007180 // The client sends an alert in response to this. The alert is sent at
7181 // handshake level because we install write secrets before read secrets and
7182 // the error is discovered when installing the read secret. (How to send
7183 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04007184 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05007185 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04007186 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04007187
David Benjamin5298ef92020-03-13 12:17:30 -04007188 // Sanity-check handshake secrets. The error is discovered while setting the
7189 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05007190 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04007191 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04007192}
7193
7194// Test that |SSL_provide_quic_data| will reject data at the wrong level.
7195TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05007196 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04007197
7198 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7199 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7200 ASSERT_TRUE(CreateClientAndServer());
7201
7202 // Send the ClientHello and ServerHello through Finished.
7203 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7204 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7205 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7206 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7207 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
7208
7209 // The client is still waiting for the ServerHello at initial
7210 // encryption.
7211 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
7212
7213 // Data cannot be provided at the next level.
7214 std::vector<uint8_t> data;
7215 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04007216 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04007217 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
7218 data.data(), data.size()));
7219 ERR_clear_error();
7220
7221 // Progress to EncryptedExtensions.
7222 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
7223 data.data(), data.size()));
7224 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7225 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7226 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
7227
7228 // Data cannot be provided at the previous level.
7229 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04007230 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04007231 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
7232 data.data(), data.size()));
7233}
7234
7235TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05007236 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04007237
7238 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7239 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7240 ASSERT_TRUE(CreateClientAndServer());
7241
7242 size_t limit =
7243 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
7244 uint8_t b = 0;
7245 for (size_t i = 0; i < limit; i++) {
7246 ASSERT_TRUE(
7247 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
7248 }
7249
7250 EXPECT_FALSE(
7251 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
7252}
7253
Steven Valdeze6eef1c2018-11-09 13:32:34 -05007254// Provide invalid post-handshake data.
7255TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05007256 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05007257
7258 g_last_session = nullptr;
7259
7260 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7261 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7262 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7263 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7264 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04007265 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05007266
7267 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
7268 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04007269 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
7270 EXPECT_FALSE(transport_->client()->has_alert());
7271 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05007272
7273 // Junk sent as part of post-handshake data should cause an error.
7274 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
7275 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
7276 kJunk, sizeof(kJunk)));
7277 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
7278}
7279
Nick Harper80ddfc72020-03-11 18:26:31 -07007280static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
7281 Span<const uint8_t> expected) {
7282 const uint8_t *received;
7283 size_t received_len;
7284 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
7285 ASSERT_EQ(received_len, expected.size());
7286 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
7287}
7288
7289TEST_F(QUICMethodTest, SetTransportParameters) {
7290 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7291 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7292 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7293
7294 ASSERT_TRUE(CreateClientAndServer());
7295 uint8_t kClientParams[] = {1, 2, 3, 4};
7296 uint8_t kServerParams[] = {5, 6, 7};
7297 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7298 sizeof(kClientParams)));
7299 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7300 sizeof(kServerParams)));
7301
7302 ASSERT_TRUE(CompleteHandshakesForQUIC());
7303 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7304 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7305}
7306
7307TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
7308 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7309 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7310 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7311
7312 ASSERT_TRUE(CreateClientAndServer());
7313 uint8_t kClientParams[] = {1, 2, 3, 4};
7314 static uint8_t kServerParams[] = {5, 6, 7};
7315 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7316 sizeof(kClientParams)));
7317 SSL_CTX_set_tlsext_servername_callback(
7318 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
7319 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
7320 sizeof(kServerParams)));
7321 return SSL_TLSEXT_ERR_OK;
7322 });
7323
7324 ASSERT_TRUE(CompleteHandshakesForQUIC());
7325 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7326 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7327}
7328
Nick Harper6bfd25c2020-03-30 17:15:19 -07007329TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
7330 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7331
7332 g_last_session = nullptr;
7333
7334 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7335 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7336 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7337 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7338
7339 ASSERT_TRUE(CreateClientAndServer());
7340 ASSERT_TRUE(CompleteHandshakesForQUIC());
7341
7342 ExpectHandshakeSuccess();
7343 EXPECT_FALSE(SSL_session_reused(client_.get()));
7344 EXPECT_FALSE(SSL_session_reused(server_.get()));
7345
7346 // The server sent NewSessionTicket messages in the handshake.
7347 EXPECT_FALSE(g_last_session);
7348 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7349 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
David Benjaminf7d37fb2023-02-04 19:45:04 -05007350 ASSERT_TRUE(g_last_session);
Nick Harper6bfd25c2020-03-30 17:15:19 -07007351
7352 // Pretend that g_last_session came from a TLS-over-TCP connection.
David Benjaminf7d37fb2023-02-04 19:45:04 -05007353 g_last_session->is_quic = false;
Nick Harper6bfd25c2020-03-30 17:15:19 -07007354
7355 // Create a second connection and verify that resumption does not occur with
7356 // a session from a non-QUIC connection. This tests that the client does not
7357 // offer over QUIC a session believed to be received over TCP. The server
7358 // believes this is a QUIC session, so if the client offered the session, the
7359 // server would have resumed it.
7360 ASSERT_TRUE(CreateClientAndServer());
7361 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
7362 SSL_set_session(client_.get(), session.get());
7363
7364 ASSERT_TRUE(CompleteHandshakesForQUIC());
7365 ExpectHandshakeSuccess();
7366 EXPECT_FALSE(SSL_session_reused(client_.get()));
7367 EXPECT_FALSE(SSL_session_reused(server_.get()));
7368}
7369
7370TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
7371 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7372
7373 g_last_session = nullptr;
7374
7375 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7376 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7377 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7378 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7379
7380 ASSERT_TRUE(CreateClientAndServer());
7381 ASSERT_TRUE(CompleteHandshakesForQUIC());
7382
7383 ExpectHandshakeSuccess();
7384 EXPECT_FALSE(SSL_session_reused(client_.get()));
7385 EXPECT_FALSE(SSL_session_reused(server_.get()));
7386
7387 // The server sent NewSessionTicket messages in the handshake.
7388 EXPECT_FALSE(g_last_session);
7389 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7390 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
David Benjaminf7d37fb2023-02-04 19:45:04 -05007391 ASSERT_TRUE(g_last_session);
Nick Harper6bfd25c2020-03-30 17:15:19 -07007392
7393 // Attempt a resumption with g_last_session using TLS_method.
7394 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
7395 ASSERT_TRUE(client_ctx);
7396
7397 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
7398
7399 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
7400 server(SSL_new(server_ctx_.get()));
7401 ASSERT_TRUE(client);
7402 ASSERT_TRUE(server);
7403 SSL_set_connect_state(client.get());
7404 SSL_set_accept_state(server.get());
7405
7406 // The TLS-over-TCP client will refuse to resume with a quic session, so
7407 // mark is_quic = false to bypass the client check to test the server check.
David Benjaminf7d37fb2023-02-04 19:45:04 -05007408 g_last_session->is_quic = false;
Nick Harper6bfd25c2020-03-30 17:15:19 -07007409 SSL_set_session(client.get(), g_last_session.get());
7410
7411 BIO *bio1, *bio2;
7412 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
7413
7414 // SSL_set_bio takes ownership.
7415 SSL_set_bio(client.get(), bio1, bio1);
7416 SSL_set_bio(server.get(), bio2, bio2);
7417 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7418
7419 EXPECT_FALSE(SSL_session_reused(client.get()));
7420 EXPECT_FALSE(SSL_session_reused(server.get()));
7421}
7422
Nick Harper72cff812020-03-26 18:06:16 -07007423TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
7424 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7425 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7426 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7427
7428 ASSERT_TRUE(CreateClientAndServer());
7429 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
7430 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7431}
7432
7433TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
7434 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7435 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7436 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7437
7438 ASSERT_TRUE(CreateClientAndServer());
7439 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
7440 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
7441}
7442
David Schinazi3d8b8c32021-01-14 11:25:49 -08007443TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
7444 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7445 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7446 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7447
7448 ASSERT_TRUE(CreateClientAndServer());
7449 uint8_t kClientParams[] = {1, 2, 3, 4};
7450 uint8_t kServerParams[] = {5, 6, 7};
7451 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7452 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7453 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7454 sizeof(kClientParams)));
7455 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7456 sizeof(kServerParams)));
7457
7458 ASSERT_TRUE(CompleteHandshakesForQUIC());
7459 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7460 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7461}
7462
7463TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
7464 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7465 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7466 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7467
7468 ASSERT_TRUE(CreateClientAndServer());
7469 uint8_t kClientParams[] = {1, 2, 3, 4};
7470 uint8_t kServerParams[] = {5, 6, 7};
7471 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7472 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7473 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7474 sizeof(kClientParams)));
7475 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7476 sizeof(kServerParams)));
7477
7478 ASSERT_TRUE(CompleteHandshakesForQUIC());
7479 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7480 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7481}
7482
7483TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
7484 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7485 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7486 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7487
7488 ASSERT_TRUE(CreateClientAndServer());
7489 uint8_t kClientParams[] = {1, 2, 3, 4};
7490 uint8_t kServerParams[] = {5, 6, 7};
7491 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7492 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7493 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7494 sizeof(kClientParams)));
7495 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7496 sizeof(kServerParams)));
7497
7498 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7499}
7500
7501TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
7502 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7503 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7504 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7505
7506 ASSERT_TRUE(CreateClientAndServer());
7507 uint8_t kClientParams[] = {1, 2, 3, 4};
7508 uint8_t kServerParams[] = {5, 6, 7};
7509 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7510 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7511 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7512 sizeof(kClientParams)));
7513 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7514 sizeof(kServerParams)));
7515
7516 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7517}
7518
David Benjaminc47bfce2021-01-20 17:10:32 -05007519// Test that the default QUIC code point is consistent with
7520// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
7521// update the two values together.
7522TEST_F(QUICMethodTest, QuicCodePointDefault) {
7523 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7524 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7525 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7526 SSL_CTX_set_select_certificate_cb(
7527 server_ctx_.get(),
7528 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7529 const uint8_t *data;
7530 size_t len;
7531 if (!SSL_early_callback_ctx_extension_get(
7532 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
7533 &len)) {
7534 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
7535 return ssl_select_cert_error;
7536 }
7537 return ssl_select_cert_success;
7538 });
7539
7540 ASSERT_TRUE(CreateClientAndServer());
7541 ASSERT_TRUE(CompleteHandshakesForQUIC());
7542}
7543
Adam Langley7540cc22019-04-18 09:56:13 -07007544extern "C" {
7545int BORINGSSL_enum_c_type_test(void);
7546}
7547
7548TEST(SSLTest, EnumTypes) {
7549 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
7550 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
7551}
7552
David Benjaminb29e1e12019-05-06 14:44:46 -05007553TEST_P(SSLVersionTest, DoubleSSLError) {
7554 // Connect the inner SSL connections.
7555 ASSERT_TRUE(Connect());
7556
7557 // Make a pair of |BIO|s which wrap |client_| and |server_|.
7558 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
7559 ASSERT_TRUE(bio_method);
7560 ASSERT_TRUE(BIO_meth_set_read(
7561 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
7562 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7563 int ret = SSL_read(ssl, out, len);
7564 int ssl_ret = SSL_get_error(ssl, ret);
7565 if (ssl_ret == SSL_ERROR_WANT_READ) {
7566 BIO_set_retry_read(bio);
7567 }
7568 return ret;
7569 }));
7570 ASSERT_TRUE(BIO_meth_set_write(
7571 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
7572 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7573 int ret = SSL_write(ssl, in, len);
7574 int ssl_ret = SSL_get_error(ssl, ret);
7575 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
7576 BIO_set_retry_write(bio);
7577 }
7578 return ret;
7579 }));
7580 ASSERT_TRUE(BIO_meth_set_ctrl(
7581 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
7582 // |SSL| objects require |BIO_flush| support.
7583 if (cmd == BIO_CTRL_FLUSH) {
7584 return 1;
7585 }
7586 return 0;
7587 }));
7588
7589 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
7590 ASSERT_TRUE(client_bio);
7591 BIO_set_data(client_bio.get(), client_.get());
7592 BIO_set_init(client_bio.get(), 1);
7593
7594 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
7595 ASSERT_TRUE(server_bio);
7596 BIO_set_data(server_bio.get(), server_.get());
7597 BIO_set_init(server_bio.get(), 1);
7598
7599 // Wrap the inner connections in another layer of SSL.
7600 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
7601 ASSERT_TRUE(client_outer);
7602 SSL_set_connect_state(client_outer.get());
7603 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
7604 client_bio.release(); // |SSL_set_bio| takes ownership.
7605
7606 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7607 ASSERT_TRUE(server_outer);
7608 SSL_set_accept_state(server_outer.get());
7609 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7610 server_bio.release(); // |SSL_set_bio| takes ownership.
7611
7612 // Configure |client_outer| to reject the server certificate.
7613 SSL_set_custom_verify(
7614 client_outer.get(), SSL_VERIFY_PEER,
7615 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7616 return ssl_verify_invalid;
7617 });
7618
7619 for (;;) {
7620 int client_ret = SSL_do_handshake(client_outer.get());
7621 int client_err = SSL_get_error(client_outer.get(), client_ret);
7622 if (client_err != SSL_ERROR_WANT_READ &&
7623 client_err != SSL_ERROR_WANT_WRITE) {
7624 // The client handshake should terminate on a certificate verification
7625 // error.
7626 EXPECT_EQ(SSL_ERROR_SSL, client_err);
David Benjaminec2a08d2024-02-21 23:21:16 -05007627 EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_SSL,
7628 SSL_R_CERTIFICATE_VERIFY_FAILED));
David Benjaminb29e1e12019-05-06 14:44:46 -05007629 break;
7630 }
7631
7632 // Run the server handshake and continue.
7633 int server_ret = SSL_do_handshake(server_outer.get());
7634 int server_err = SSL_get_error(server_outer.get(), server_ret);
7635 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7636 server_err == SSL_ERROR_WANT_READ ||
7637 server_err == SSL_ERROR_WANT_WRITE);
7638 }
7639}
7640
David Benjamin1b819472020-06-09 14:01:02 -04007641TEST_P(SSLVersionTest, SameKeyResume) {
7642 uint8_t key[48];
7643 RAND_bytes(key, sizeof(key));
7644
7645 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7646 ASSERT_TRUE(server_ctx2);
7647 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7648 ASSERT_TRUE(
7649 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7650 ASSERT_TRUE(
7651 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7652
7653 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7654 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7655 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7656
7657 // Establish a session for |server_ctx_|.
7658 bssl::UniquePtr<SSL_SESSION> session =
7659 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7660 ASSERT_TRUE(session);
7661 ClientConfig config;
7662 config.session = session.get();
7663
7664 // Resuming with |server_ctx_| again works.
7665 bssl::UniquePtr<SSL> client, server;
7666 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7667 server_ctx_.get(), config));
7668 EXPECT_TRUE(SSL_session_reused(client.get()));
7669 EXPECT_TRUE(SSL_session_reused(server.get()));
7670
7671 // Resuming with |server_ctx2| also works.
7672 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7673 server_ctx2.get(), config));
7674 EXPECT_TRUE(SSL_session_reused(client.get()));
7675 EXPECT_TRUE(SSL_session_reused(server.get()));
7676}
7677
7678TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7679 uint8_t key1[48], key2[48];
7680 RAND_bytes(key1, sizeof(key1));
7681 RAND_bytes(key2, sizeof(key2));
7682
7683 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7684 ASSERT_TRUE(server_ctx2);
7685 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7686 ASSERT_TRUE(
7687 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7688 ASSERT_TRUE(
7689 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7690
7691 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7692 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7693 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7694
7695 // Establish a session for |server_ctx_|.
7696 bssl::UniquePtr<SSL_SESSION> session =
7697 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7698 ASSERT_TRUE(session);
7699 ClientConfig config;
7700 config.session = session.get();
7701
7702 // Resuming with |server_ctx_| again works.
7703 bssl::UniquePtr<SSL> client, server;
7704 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7705 server_ctx_.get(), config));
7706 EXPECT_TRUE(SSL_session_reused(client.get()));
7707 EXPECT_TRUE(SSL_session_reused(server.get()));
7708
7709 // Resuming with |server_ctx2| does not work.
7710 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7711 server_ctx2.get(), config));
7712 EXPECT_FALSE(SSL_session_reused(client.get()));
7713 EXPECT_FALSE(SSL_session_reused(server.get()));
7714}
7715
7716TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7717 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7718 ASSERT_TRUE(server_ctx2);
7719 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7720
7721 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7722 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7723 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7724
7725 // Establish a session for |server_ctx_|.
7726 bssl::UniquePtr<SSL_SESSION> session =
7727 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7728 ASSERT_TRUE(session);
7729 ClientConfig config;
7730 config.session = session.get();
7731
7732 // Resuming with |server_ctx_| again works.
7733 bssl::UniquePtr<SSL> client, server;
7734 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7735 server_ctx_.get(), config));
7736 EXPECT_TRUE(SSL_session_reused(client.get()));
7737 EXPECT_TRUE(SSL_session_reused(server.get()));
7738
7739 // Resuming with |server_ctx2| does not work.
7740 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7741 server_ctx2.get(), config));
7742 EXPECT_FALSE(SSL_session_reused(client.get()));
7743 EXPECT_FALSE(SSL_session_reused(server.get()));
7744}
7745
Adam Langley47cefed2021-05-26 13:36:40 -07007746Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7747 const SSL_SESSION *session = SSL_get_session(ssl);
7748 unsigned len;
7749 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7750 return MakeConstSpan(data, len);
7751}
7752
7753TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7754 // This checks that the session IDs at client and server match after a ticket
7755 // resumption. It's unclear whether this should be true, but Envoy depends
7756 // on it in their tests so this will give an early signal if we break it.
7757 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7758 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7759
7760 bssl::UniquePtr<SSL_SESSION> session =
7761 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7762
7763 bssl::UniquePtr<SSL> client, server;
7764 ClientConfig config;
7765 config.session = session.get();
David Benjaminf7d37fb2023-02-04 19:45:04 -05007766 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
Adam Langley47cefed2021-05-26 13:36:40 -07007767 server_ctx_.get(), config));
7768 EXPECT_TRUE(SSL_session_reused(client.get()));
7769 EXPECT_TRUE(SSL_session_reused(server.get()));
7770
7771 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7772}
7773
David Benjamin10fef972022-08-30 11:38:51 -04007774static void WriteHelloRequest(SSL *server) {
7775 // This function assumes TLS 1.2 with ChaCha20-Poly1305.
7776 ASSERT_EQ(SSL_version(server), TLS1_2_VERSION);
7777 ASSERT_EQ(SSL_CIPHER_get_cipher_nid(SSL_get_current_cipher(server)),
7778 NID_chacha20_poly1305);
David Benjamin0e7dbd52019-05-15 16:01:18 -04007779
7780 // Encrypt a HelloRequest.
7781 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7782#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7783 // Fuzzer-mode records are unencrypted.
7784 uint8_t record[5 + sizeof(in)];
7785 record[0] = SSL3_RT_HANDSHAKE;
7786 record[1] = 3;
7787 record[2] = 3; // TLS 1.2
7788 record[3] = 0;
7789 record[4] = sizeof(record) - 5;
7790 memcpy(record + 5, in, sizeof(in));
7791#else
7792 // Extract key material from |server|.
7793 static const size_t kKeyLen = 32;
7794 static const size_t kNonceLen = 12;
David Benjamin10fef972022-08-30 11:38:51 -04007795 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007796 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
David Benjamin10fef972022-08-30 11:38:51 -04007797 ASSERT_TRUE(SSL_generate_key_block(server, key_block, sizeof(key_block)));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007798 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7799 Span<uint8_t> nonce =
7800 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7801
7802 uint8_t ad[13];
David Benjamin10fef972022-08-30 11:38:51 -04007803 uint64_t seq = SSL_get_write_sequence(server);
David Benjamin0e7dbd52019-05-15 16:01:18 -04007804 for (size_t i = 0; i < 8; i++) {
7805 // The nonce is XORed with the sequence number.
7806 nonce[11 - i] ^= uint8_t(seq);
7807 ad[7 - i] = uint8_t(seq);
7808 seq >>= 8;
7809 }
7810
7811 ad[8] = SSL3_RT_HANDSHAKE;
7812 ad[9] = 3;
7813 ad[10] = 3; // TLS 1.2
7814 ad[11] = 0;
7815 ad[12] = sizeof(in);
7816
7817 uint8_t record[5 + sizeof(in) + 16];
7818 record[0] = SSL3_RT_HANDSHAKE;
7819 record[1] = 3;
7820 record[2] = 3; // TLS 1.2
7821 record[3] = 0;
7822 record[4] = sizeof(record) - 5;
7823
7824 ScopedEVP_AEAD_CTX aead;
7825 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7826 key.data(), key.size(),
7827 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7828 size_t len;
7829 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7830 sizeof(record) - 5, nonce.data(), nonce.size(),
7831 in, sizeof(in), ad, sizeof(ad)));
7832 ASSERT_EQ(sizeof(record) - 5, len);
7833#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7834
7835 ASSERT_EQ(int(sizeof(record)),
David Benjamin10fef972022-08-30 11:38:51 -04007836 BIO_write(SSL_get_wbio(server), record, sizeof(record)));
7837}
7838
7839TEST(SSLTest, WriteWhileExplicitRenegotiate) {
7840 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
7841 ASSERT_TRUE(ctx);
7842
7843 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7844 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7845 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7846 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7847
7848 bssl::UniquePtr<SSL> client, server;
7849 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
7850 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
7851 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7852
7853 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7854
7855 // Write "hello" until the buffer is full, so |client| has a pending write.
7856 size_t num_writes = 0;
7857 for (;;) {
7858 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7859 if (ret != int(sizeof(kInput))) {
7860 ASSERT_EQ(-1, ret);
7861 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7862 break;
7863 }
7864 num_writes++;
7865 }
7866
7867 ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007868
7869 // |SSL_read| should pick up the HelloRequest.
7870 uint8_t byte;
7871 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7872 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7873
7874 // Drain the data from the |client|.
7875 uint8_t buf[sizeof(kInput)];
7876 for (size_t i = 0; i < num_writes; i++) {
7877 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7878 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7879 }
7880
7881 // |client| should be able to finish the pending write and continue to write,
7882 // despite the paused HelloRequest.
7883 ASSERT_EQ(int(sizeof(kInput)),
7884 SSL_write(client.get(), kInput, sizeof(kInput)));
7885 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7886 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7887
7888 ASSERT_EQ(int(sizeof(kInput)),
7889 SSL_write(client.get(), kInput, sizeof(kInput)));
7890 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7891 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7892
7893 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7894 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7895 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7896
7897 ASSERT_TRUE(SSL_renegotiate(client.get()));
7898 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7899 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7900
7901 // We never renegotiate as a server.
7902 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7903 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
David Benjaminec2a08d2024-02-21 23:21:16 -05007904 EXPECT_TRUE(
7905 ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007906}
7907
David Benjamin10fef972022-08-30 11:38:51 -04007908TEST(SSLTest, ConnectionPropertiesDuringRenegotiate) {
7909 // Configure known connection properties, so we can check against them.
7910 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7911 ASSERT_TRUE(ctx);
7912 bssl::UniquePtr<X509> cert = GetTestCertificate();
7913 ASSERT_TRUE(cert);
7914 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7915 ASSERT_TRUE(key);
7916 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7917 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7918 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7919 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7920 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7921 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
David Benjamin2da5ba92023-05-26 21:23:39 -04007922 ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), "X25519"));
David Benjamin10fef972022-08-30 11:38:51 -04007923 ASSERT_TRUE(SSL_CTX_set1_sigalgs_list(ctx.get(), "rsa_pkcs1_sha256"));
7924
7925 // Connect a client and server that accept renegotiation.
7926 bssl::UniquePtr<SSL> client, server;
7927 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
7928 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7929 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7930
7931 auto check_properties = [&] {
7932 EXPECT_EQ(SSL_version(client.get()), TLS1_2_VERSION);
7933 const SSL_CIPHER *cipher = SSL_get_current_cipher(client.get());
7934 ASSERT_TRUE(cipher);
7935 EXPECT_EQ(SSL_CIPHER_get_id(cipher),
7936 uint32_t{TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256});
David Benjamin335523a2023-05-26 21:55:56 -04007937 EXPECT_EQ(SSL_get_group_id(client.get()), SSL_GROUP_X25519);
David Benjamin6cf98202023-05-26 22:03:30 -04007938 EXPECT_EQ(SSL_get_negotiated_group(client.get()), NID_X25519);
David Benjamin10fef972022-08-30 11:38:51 -04007939 EXPECT_EQ(SSL_get_peer_signature_algorithm(client.get()),
7940 SSL_SIGN_RSA_PKCS1_SHA256);
7941 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
7942 ASSERT_TRUE(peer);
7943 EXPECT_EQ(X509_cmp(cert.get(), peer.get()), 0);
7944 };
7945 check_properties();
7946
7947 // The server sends a HelloRequest.
7948 ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
7949
7950 // Reading from the client will consume the HelloRequest, start a
7951 // renegotiation, and then block on a ServerHello from the server.
7952 uint8_t byte;
7953 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7954 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7955
7956 // Connection properties should continue to report values from the original
7957 // handshake.
7958 check_properties();
7959}
David Benjaminf9e0cda2020-03-23 18:29:09 -04007960
7961TEST(SSLTest, CopyWithoutEarlyData) {
7962 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007963 bssl::UniquePtr<SSL_CTX> server_ctx(
7964 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007965 ASSERT_TRUE(client_ctx);
7966 ASSERT_TRUE(server_ctx);
7967
David Benjaminf9e0cda2020-03-23 18:29:09 -04007968 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7969 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7970 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7971 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7972
7973 bssl::UniquePtr<SSL_SESSION> session =
7974 CreateClientSession(client_ctx.get(), server_ctx.get());
7975 ASSERT_TRUE(session);
7976
7977 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007978 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007979 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7980 server_ctx.get()));
7981 SSL_set_session(client.get(), session.get());
7982 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007983 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7984 EXPECT_TRUE(SSL_in_early_data(client.get()));
7985
7986 // |SSL_SESSION_copy_without_early_data| should disable early data but
7987 // still resume the session.
7988 bssl::UniquePtr<SSL_SESSION> session2(
7989 SSL_SESSION_copy_without_early_data(session.get()));
7990 ASSERT_TRUE(session2);
7991 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007992 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7993 server_ctx.get()));
7994 SSL_set_session(client.get(), session2.get());
7995 SSL_set_early_data_enabled(client.get(), 1);
7996 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007997 EXPECT_TRUE(SSL_session_reused(client.get()));
7998 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7999 SSL_get_early_data_reason(client.get()));
8000
8001 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
8002 // when passed an early-data-incapable session.
8003 bssl::UniquePtr<SSL_SESSION> session3(
8004 SSL_SESSION_copy_without_early_data(session2.get()));
8005 EXPECT_EQ(session2.get(), session3.get());
8006}
8007
Adam Langley53a17f52020-05-26 14:44:07 -07008008TEST(SSLTest, ProcessTLS13NewSessionTicket) {
8009 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07008010 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04008011 bssl::UniquePtr<SSL_CTX> server_ctx(
8012 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07008013 ASSERT_TRUE(client_ctx);
8014 ASSERT_TRUE(server_ctx);
8015 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
8016 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
8017 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
8018 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07008019
8020 bssl::UniquePtr<SSL> client, server;
8021 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8022 server_ctx.get()));
8023 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
8024
8025 // Process a TLS 1.3 NewSessionTicket.
8026 static const uint8_t kTicket[] = {
8027 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
8028 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
8029 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
8030 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
8031 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
8032 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
8033 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
8034 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
8035 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
8036 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
8037 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
8038 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
8039 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
8040 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
8041 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
8042 0x00, 0x00,
8043 };
8044 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
8045 client.get(), kTicket, sizeof(kTicket)));
8046 ASSERT_TRUE(session);
8047 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
8048
8049 uint8_t *session_buf = nullptr;
8050 size_t session_length = 0;
8051 ASSERT_TRUE(
8052 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
8053 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
8054 ASSERT_TRUE(session_buf);
8055 ASSERT_GT(session_length, 0u);
8056
8057 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
8058 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
8059 sizeof(kTicket)));
8060
8061 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
8062 // handshake completes.
8063 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
8064 ASSERT_TRUE(client2);
8065 SSL_set_connect_state(client2.get());
8066 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
8067 sizeof(kTicket)));
8068}
8069
David Benjamin3989c992020-10-09 14:12:06 -04008070TEST(SSLTest, BIO) {
8071 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04008072 bssl::UniquePtr<SSL_CTX> server_ctx(
8073 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04008074 ASSERT_TRUE(client_ctx);
8075 ASSERT_TRUE(server_ctx);
8076
David Benjamin3989c992020-10-09 14:12:06 -04008077 for (bool take_ownership : {true, false}) {
8078 // For simplicity, get the handshake out of the way first.
8079 bssl::UniquePtr<SSL> client, server;
8080 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8081 server_ctx.get()));
8082
8083 // Wrap |client| in an SSL BIO.
8084 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
8085 ASSERT_TRUE(client_bio);
8086 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
8087 if (take_ownership) {
8088 client.release();
8089 }
8090
8091 // Flushing the BIO should not crash.
8092 EXPECT_EQ(1, BIO_flush(client_bio.get()));
8093
8094 // Exchange some data.
8095 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
8096 uint8_t buf[5];
8097 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
8098 EXPECT_EQ(Bytes("hello"), Bytes(buf));
8099
8100 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
8101 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
8102 EXPECT_EQ(Bytes("world"), Bytes(buf));
8103
8104 // |BIO_should_read| should work.
8105 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
8106 EXPECT_TRUE(BIO_should_read(client_bio.get()));
8107
8108 // Writing data should eventually exceed the buffer size and fail, reporting
8109 // |BIO_should_write|.
8110 int ret;
8111 for (int i = 0; i < 1024; i++) {
David Benjamina4385192023-03-25 01:26:49 -04008112 const uint8_t kZeros[1024] = {0};
8113 ret = BIO_write(client_bio.get(), kZeros, sizeof(kZeros));
David Benjamin3989c992020-10-09 14:12:06 -04008114 if (ret <= 0) {
8115 break;
8116 }
8117 }
8118 EXPECT_EQ(-1, ret);
8119 EXPECT_TRUE(BIO_should_write(client_bio.get()));
8120 }
8121}
8122
David Benjamin12a3e7e2021-04-13 11:47:36 -04008123TEST(SSLTest, ALPNConfig) {
8124 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8125 ASSERT_TRUE(ctx);
8126 bssl::UniquePtr<X509> cert = GetTestCertificate();
8127 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8128 ASSERT_TRUE(cert);
8129 ASSERT_TRUE(key);
8130 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
8131 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
8132
8133 // Set up some machinery to check the configured ALPN against what is actually
8134 // sent over the wire. Note that the ALPN callback is only called when the
8135 // client offers ALPN.
8136 std::vector<uint8_t> observed_alpn;
8137 SSL_CTX_set_alpn_select_cb(
8138 ctx.get(),
8139 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
8140 unsigned in_len, void *arg) -> int {
8141 std::vector<uint8_t> *observed_alpn_ptr =
8142 static_cast<std::vector<uint8_t> *>(arg);
8143 observed_alpn_ptr->assign(in, in + in_len);
8144 return SSL_TLSEXT_ERR_NOACK;
8145 },
8146 &observed_alpn);
8147 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
8148 observed_alpn.clear();
8149 bssl::UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05008150 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin12a3e7e2021-04-13 11:47:36 -04008151 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
8152 };
8153
8154 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
8155 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
8156 0x03, 'b', 'a', 'r'};
8157 EXPECT_EQ(0,
8158 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
8159 check_alpn_proto(kValidList);
8160
8161 // Invalid lists are rejected.
8162 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
8163 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
8164 sizeof(kInvalidList)));
8165
8166 // Empty lists are valid and are interpreted as disabling ALPN.
8167 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
8168 check_alpn_proto({});
8169}
8170
Victor Tan558960d2023-06-23 15:04:33 +00008171// This is a basic unit-test class to verify completing handshake successfully,
8172// sending the correct codepoint extension and having correct application
8173// setting on different combination of ALPS codepoint settings. More integration
8174// tests on runner.go.
8175class AlpsNewCodepointTest : public testing::Test {
8176 protected:
8177 void SetUp() override {
8178 client_ctx_.reset(SSL_CTX_new(TLS_method()));
8179 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
8180 ASSERT_TRUE(client_ctx_);
8181 ASSERT_TRUE(server_ctx_);
8182 }
8183
Victor Tan558960d2023-06-23 15:04:33 +00008184 void SetUpApplicationSetting() {
8185 static const uint8_t alpn[] = {0x03, 'f', 'o', 'o'};
8186 static const uint8_t proto[] = {'f', 'o', 'o'};
8187 static const uint8_t alps[] = {0x04, 'a', 'l', 'p', 's'};
8188 // SSL_set_alpn_protos's return value is backwards. It returns zero on
8189 // success and one on failure.
8190 ASSERT_FALSE(SSL_set_alpn_protos(client_.get(), alpn, sizeof(alpn)));
8191 SSL_CTX_set_alpn_select_cb(
8192 server_ctx_.get(),
8193 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
8194 unsigned in_len, void *arg) -> int {
8195 return SSL_select_next_proto(
8196 const_cast<uint8_t **>(out), out_len, in, in_len,
8197 alpn, sizeof(alpn)) == OPENSSL_NPN_NEGOTIATED
8198 ? SSL_TLSEXT_ERR_OK
8199 : SSL_TLSEXT_ERR_NOACK;
8200 },
8201 nullptr);
8202 ASSERT_TRUE(SSL_add_application_settings(client_.get(), proto,
8203 sizeof(proto), nullptr, 0));
8204 ASSERT_TRUE(SSL_add_application_settings(server_.get(), proto,
8205 sizeof(proto), alps, sizeof(alps)));
8206 }
8207
8208 bssl::UniquePtr<SSL_CTX> client_ctx_;
8209 bssl::UniquePtr<SSL_CTX> server_ctx_;
8210
8211 bssl::UniquePtr<SSL> client_;
8212 bssl::UniquePtr<SSL> server_;
8213};
8214
8215TEST_F(AlpsNewCodepointTest, Enabled) {
Victor Tan3309ca62023-09-29 01:57:01 +00008216 SetUpExpectedNewCodePoint(server_ctx_.get());
Victor Tan558960d2023-06-23 15:04:33 +00008217
8218 ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8219 server_ctx_.get()));
8220
8221 SSL_set_alps_use_new_codepoint(client_.get(), 1);
8222 SSL_set_alps_use_new_codepoint(server_.get(), 1);
8223
8224 SetUpApplicationSetting();
8225 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8226 ASSERT_TRUE(SSL_has_application_settings(client_.get()));
8227}
8228
8229TEST_F(AlpsNewCodepointTest, Disabled) {
8230 // Both client and server disable alps new codepoint.
Victor Tan3309ca62023-09-29 01:57:01 +00008231 SetUpExpectedOldCodePoint(server_ctx_.get());
Victor Tan558960d2023-06-23 15:04:33 +00008232
8233 ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8234 server_ctx_.get()));
8235
8236 SSL_set_alps_use_new_codepoint(client_.get(), 0);
8237 SSL_set_alps_use_new_codepoint(server_.get(), 0);
8238
8239 SetUpApplicationSetting();
8240 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8241 ASSERT_TRUE(SSL_has_application_settings(client_.get()));
8242}
8243
8244TEST_F(AlpsNewCodepointTest, ClientOnly) {
8245 // If client set new codepoint but server doesn't set, server ignores it.
Victor Tan3309ca62023-09-29 01:57:01 +00008246 SetUpExpectedNewCodePoint(server_ctx_.get());
Victor Tan558960d2023-06-23 15:04:33 +00008247
8248 ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8249 server_ctx_.get()));
8250
8251 SSL_set_alps_use_new_codepoint(client_.get(), 1);
8252 SSL_set_alps_use_new_codepoint(server_.get(), 0);
8253
8254 SetUpApplicationSetting();
8255 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8256 ASSERT_FALSE(SSL_has_application_settings(client_.get()));
8257}
8258
8259TEST_F(AlpsNewCodepointTest, ServerOnly) {
8260 // If client doesn't set new codepoint, while server set.
Victor Tan3309ca62023-09-29 01:57:01 +00008261 SetUpExpectedOldCodePoint(server_ctx_.get());
Victor Tan558960d2023-06-23 15:04:33 +00008262
8263 ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8264 server_ctx_.get()));
8265
8266 SSL_set_alps_use_new_codepoint(client_.get(), 0);
8267 SSL_set_alps_use_new_codepoint(server_.get(), 1);
8268
8269 SetUpApplicationSetting();
8270 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8271 ASSERT_FALSE(SSL_has_application_settings(client_.get()));
8272}
8273
David Benjamin2f3958a2021-04-16 11:55:23 -04008274// Test that the key usage checker can correctly handle issuerUID and
8275// subjectUID. See https://crbug.com/1199744.
8276TEST(SSLTest, KeyUsageWithUIDs) {
8277 static const char kGoodKeyUsage[] = R"(
8278-----BEGIN CERTIFICATE-----
8279MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
8280AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
8281aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
8282CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
8283ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
82844r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
8285Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
8286ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
8287A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
828834EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
82894Z7qDhjIhiF4dM0uEDYRVA==
8290-----END CERTIFICATE-----
8291)";
8292 static const char kBadKeyUsage[] = R"(
8293-----BEGIN CERTIFICATE-----
8294MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
8295AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
8296aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
8297CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
8298ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
82994r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
8300Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
8301ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
8302A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
8303taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
8304RHrQbWsFUakETXL9QMlegh5t
8305-----END CERTIFICATE-----
8306)";
8307
8308 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
8309 ASSERT_TRUE(good);
8310 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
8311 ASSERT_TRUE(bad);
8312
8313 // We check key usage when configuring EC certificates to distinguish ECDSA
8314 // and ECDH.
8315 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8316 ASSERT_TRUE(ctx);
8317 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
8318 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
8319}
8320
David Benjamin9b2cdb72021-04-01 23:21:53 -04008321// Test that |SSL_can_release_private_key| reports true as early as expected.
8322// The internal asserts in the library check we do not report true too early.
8323TEST(SSLTest, CanReleasePrivateKey) {
8324 bssl::UniquePtr<SSL_CTX> client_ctx =
8325 CreateContextWithTestCertificate(TLS_method());
8326 ASSERT_TRUE(client_ctx);
8327 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8328
8329 // Note this assumes the transport buffer is large enough to fit the client
8330 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
8331 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
8332 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
8333 // Write the ClientHello.
8334 ASSERT_EQ(-1, SSL_do_handshake(client));
8335 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
8336
8337 // Consume the ClientHello and write the server flight.
8338 ASSERT_EQ(-1, SSL_do_handshake(server));
8339 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
8340
8341 EXPECT_TRUE(SSL_can_release_private_key(server));
8342 };
8343
8344 {
8345 SCOPED_TRACE("TLS 1.2 ECDHE");
8346 bssl::UniquePtr<SSL_CTX> server_ctx(
8347 CreateContextWithTestCertificate(TLS_method()));
8348 ASSERT_TRUE(server_ctx);
8349 ASSERT_TRUE(
8350 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
8351 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
8352 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
8353 // Configure the server to request client certificates, so we can also test
8354 // the client half.
8355 SSL_CTX_set_custom_verify(
8356 server_ctx.get(), SSL_VERIFY_PEER,
8357 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
8358 bssl::UniquePtr<SSL> client, server;
8359 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8360 server_ctx.get()));
8361 check_first_server_round_trip(client.get(), server.get());
8362
8363 // Consume the server flight and write the client response. The client still
8364 // has a Finished message to consume but can also release its key early.
8365 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
8366 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8367 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
8368
8369 // However, a client that has not disabled renegotiation can never release
8370 // the key.
8371 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8372 server_ctx.get()));
8373 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
8374 check_first_server_round_trip(client.get(), server.get());
8375 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
8376 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8377 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
8378 }
8379
8380 {
8381 SCOPED_TRACE("TLS 1.2 resumption");
8382 bssl::UniquePtr<SSL_CTX> server_ctx(
8383 CreateContextWithTestCertificate(TLS_method()));
8384 ASSERT_TRUE(server_ctx);
8385 ASSERT_TRUE(
8386 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
8387 bssl::UniquePtr<SSL_SESSION> session =
8388 CreateClientSession(client_ctx.get(), server_ctx.get());
8389 ASSERT_TRUE(session);
8390 bssl::UniquePtr<SSL> client, server;
8391 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8392 server_ctx.get()));
8393 SSL_set_session(client.get(), session.get());
8394 check_first_server_round_trip(client.get(), server.get());
8395 }
8396
8397 {
8398 SCOPED_TRACE("TLS 1.3 1-RTT");
8399 bssl::UniquePtr<SSL_CTX> server_ctx(
8400 CreateContextWithTestCertificate(TLS_method()));
8401 ASSERT_TRUE(server_ctx);
8402 ASSERT_TRUE(
8403 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
8404 bssl::UniquePtr<SSL> client, server;
8405 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8406 server_ctx.get()));
8407 check_first_server_round_trip(client.get(), server.get());
8408 }
8409
8410 {
8411 SCOPED_TRACE("TLS 1.3 resumption");
8412 bssl::UniquePtr<SSL_CTX> server_ctx(
8413 CreateContextWithTestCertificate(TLS_method()));
8414 ASSERT_TRUE(server_ctx);
8415 ASSERT_TRUE(
8416 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
8417 bssl::UniquePtr<SSL_SESSION> session =
8418 CreateClientSession(client_ctx.get(), server_ctx.get());
8419 ASSERT_TRUE(session);
8420 bssl::UniquePtr<SSL> client, server;
8421 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8422 server_ctx.get()));
8423 SSL_set_session(client.get(), session.get());
8424 check_first_server_round_trip(client.get(), server.get());
8425 }
8426}
8427
David Benjamine9c5d722021-06-09 17:43:16 -04008428// GetExtensionOrder sets |*out| to the list of extensions a client attached to
8429// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
8430// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
8431// will be set to the ClientHelloInner's extensions, rather than
8432// ClientHelloOuter.
8433static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
8434 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
8435 struct AppData {
8436 std::vector<uint16_t> *out;
8437 bool decrypt_ech;
8438 bool callback_done = false;
8439 };
8440 AppData app_data;
8441 app_data.out = out;
8442 app_data.decrypt_ech = decrypt_ech;
8443
8444 bssl::UniquePtr<SSL_CTX> server_ctx =
8445 CreateContextWithTestCertificate(TLS_method());
8446 if (!server_ctx || //
8447 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
8448 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
8449 return false;
8450 }
8451
8452 // Configure the server to record the ClientHello extension order. We use a
8453 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
8454 SSL_CTX_set_select_certificate_cb(
8455 server_ctx.get(),
8456 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
8457 AppData *app_data_ptr = static_cast<AppData *>(
8458 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
8459 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
8460 SSL_ech_accepted(client_hello->ssl));
8461
8462 app_data_ptr->out->clear();
8463 CBS extensions;
8464 CBS_init(&extensions, client_hello->extensions,
8465 client_hello->extensions_len);
8466 while (CBS_len(&extensions)) {
8467 uint16_t type;
8468 CBS body;
8469 if (!CBS_get_u16(&extensions, &type) ||
8470 !CBS_get_u16_length_prefixed(&extensions, &body)) {
8471 return ssl_select_cert_error;
8472 }
8473 app_data_ptr->out->push_back(type);
8474 }
8475
8476 // Don't bother completing the handshake.
8477 app_data_ptr->callback_done = true;
8478 return ssl_select_cert_error;
8479 });
8480
8481 bssl::UniquePtr<SSL> client, server;
8482 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
8483 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
8484 return false;
8485 }
8486
8487 // Run the handshake far enough to process the ClientHello.
8488 SSL_do_handshake(client.get());
8489 SSL_do_handshake(server.get());
8490 return app_data.callback_done;
8491}
8492
8493// Test that, when extension permutation is enabled, the ClientHello extension
8494// order changes, both with and without ECH, and in both ClientHelloInner and
8495// ClientHelloOuter.
8496TEST(SSLTest, PermuteExtensions) {
8497 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
8498 ASSERT_TRUE(keys);
8499 for (bool offer_ech : {false, true}) {
8500 SCOPED_TRACE(offer_ech);
8501 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
8502 for (bool decrypt_ech : {false, true}) {
8503 SCOPED_TRACE(decrypt_ech);
8504 if (!offer_ech && decrypt_ech) {
8505 continue;
8506 }
8507
8508 // When extension permutation is disabled, the order should be consistent.
8509 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8510 ASSERT_TRUE(ctx);
8511 std::vector<uint16_t> order1, order2;
8512 ASSERT_TRUE(
8513 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8514 ASSERT_TRUE(
8515 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8516 EXPECT_EQ(order1, order2);
8517
8518 ctx.reset(SSL_CTX_new(TLS_method()));
8519 ASSERT_TRUE(ctx);
8520 SSL_CTX_set_permute_extensions(ctx.get(), 1);
8521
8522 // When extension permutation is enabled, each ClientHello should have a
8523 // different order.
8524 //
8525 // This test is inherently flaky, so we run it multiple times. We send at
8526 // least five extensions by default from TLS 1.3: supported_versions,
8527 // key_share, supported_groups, psk_key_exchange_modes, and
8528 // signature_algorithms. That means the probability of a false negative is
8529 // at most 1/120. Repeating the test 14 times lowers false negative rate
8530 // to under 2^-96.
8531 ASSERT_TRUE(
8532 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8533 EXPECT_GE(order1.size(), 5u);
8534 static const int kNumIterations = 14;
8535 bool passed = false;
8536 for (int i = 0; i < kNumIterations; i++) {
8537 ASSERT_TRUE(
8538 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8539 if (order1 != order2) {
8540 passed = true;
8541 break;
8542 }
8543 }
8544 EXPECT_TRUE(passed) << "Extensions were not permuted";
8545 }
8546 }
8547}
8548
Adam Langley7e7e6b62021-12-06 13:04:07 -08008549TEST(SSLTest, HostMatching) {
David Benjaminc3c540b2021-12-08 15:12:51 -05008550 static const char kCertPEM[] = R"(
8551-----BEGIN CERTIFICATE-----
8552MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw
8553DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2
8554MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD
8555VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO
8556Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW
8557ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr
8558BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3
8559Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP
8560YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD
8561AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu
85625DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY=
8563-----END CERTIFICATE-----
8564)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008565 bssl::UniquePtr<X509> cert(CertFromPEM(kCertPEM));
8566 ASSERT_TRUE(cert);
David Benjaminc3c540b2021-12-08 15:12:51 -05008567 static const char kCertNoSANsPEM[] = R"(
8568-----BEGIN CERTIFICATE-----
8569MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw
8570EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy
8571MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV
8572MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
8573u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw
8574L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG
8575CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG
8576SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW
8577pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4=
8578-----END CERTIFICATE-----
8579)";
8580 bssl::UniquePtr<X509> cert_no_sans(CertFromPEM(kCertNoSANsPEM));
8581 ASSERT_TRUE(cert_no_sans);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008582
David Benjaminc3c540b2021-12-08 15:12:51 -05008583 static const char kKeyPEM[] = R"(
8584-----BEGIN PRIVATE KEY-----
8585MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ
8586MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+
8587RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
8588-----END PRIVATE KEY-----
8589)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008590 bssl::UniquePtr<EVP_PKEY> key(KeyFromPEM(kKeyPEM));
8591 ASSERT_TRUE(key);
8592
Adam Langley7e7e6b62021-12-06 13:04:07 -08008593 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8594 ASSERT_TRUE(client_ctx);
8595 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8596 cert.get()));
David Benjaminc3c540b2021-12-08 15:12:51 -05008597 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8598 cert_no_sans.get()));
Adam Langley7e7e6b62021-12-06 13:04:07 -08008599 SSL_CTX_set_verify(client_ctx.get(),
8600 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
8601 nullptr);
Bob Beck28f96c22022-12-06 16:07:05 -07008602 X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
8603 X509_V_FLAG_NO_CHECK_TIME);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008604
8605 struct TestCase {
David Benjaminc3c540b2021-12-08 15:12:51 -05008606 X509 *cert;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008607 std::string hostname;
8608 unsigned flags;
8609 bool should_match;
8610 };
8611 std::vector<TestCase> kTests = {
8612 // These two names are present as SANs in the certificate.
David Benjaminc3c540b2021-12-08 15:12:51 -05008613 {cert.get(), "example1.com", 0, true},
8614 {cert.get(), "example2.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008615 // This is the CN of the certificate, but that shouldn't matter if a SAN
8616 // extension is present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008617 {cert.get(), "example3.com", 0, false},
8618 // If the SAN is not present, we, for now, look for DNS names in the CN.
8619 {cert_no_sans.get(), "example3.com", 0, true},
8620 // ... but this can be turned off.
8621 {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT,
8622 false},
8623 // a*.example4.com is a SAN, but is invalid.
8624 {cert.get(), "abc.example4.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008625 // *.example5.com is a SAN in the certificate, which is a normal and valid
8626 // wildcard.
David Benjaminc3c540b2021-12-08 15:12:51 -05008627 {cert.get(), "abc.example5.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008628 // This name is not present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008629 {cert.get(), "notexample1.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008630 // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a
8631 // hostname that happens to be its textual representation.
David Benjaminc3c540b2021-12-08 15:12:51 -05008632 {cert.get(), "1.2.3.4", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008633 };
8634
Adam Langley7e7e6b62021-12-06 13:04:07 -08008635 for (const TestCase &test : kTests) {
8636 SCOPED_TRACE(test.hostname);
David Benjaminc3c540b2021-12-08 15:12:51 -05008637
8638 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8639 ASSERT_TRUE(server_ctx);
8640 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert));
8641 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8642
8643 ClientConfig config;
8644 bssl::UniquePtr<SSL> client, server;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008645 config.verify_hostname = test.hostname;
8646 config.hostflags = test.flags;
8647 EXPECT_EQ(test.should_match,
8648 ConnectClientAndServer(&client, &server, client_ctx.get(),
8649 server_ctx.get(), config));
8650 }
8651}
8652
David Benjamin3f180b82022-05-09 17:45:18 -04008653TEST(SSLTest, NumTickets) {
8654 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8655 ASSERT_TRUE(server_ctx);
8656 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8657 ASSERT_TRUE(client_ctx);
8658 bssl::UniquePtr<X509> cert = GetTestCertificate();
8659 ASSERT_TRUE(cert);
8660 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8661 ASSERT_TRUE(key);
8662 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
8663 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8664 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8665
8666 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8667 static size_t ticket_count;
8668 SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int {
8669 ticket_count++;
8670 return 0;
8671 });
8672
8673 auto count_tickets = [&]() -> size_t {
8674 ticket_count = 0;
8675 bssl::UniquePtr<SSL> client, server;
8676 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
8677 server_ctx.get()) ||
8678 !FlushNewSessionTickets(client.get(), server.get())) {
8679 ADD_FAILURE() << "Could not run handshake";
8680 return 0;
8681 }
8682 return ticket_count;
8683 };
8684
8685 // By default, we should send two tickets.
8686 EXPECT_EQ(count_tickets(), 2u);
8687
8688 for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) {
8689 SCOPED_TRACE(num_tickets);
8690 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets));
David Benjamin5697a922022-07-21 10:35:59 -07008691 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), num_tickets);
David Benjamin3f180b82022-05-09 17:45:18 -04008692 EXPECT_EQ(count_tickets(), num_tickets);
8693 }
8694
8695 // Configuring too many tickets causes us to stop at some point.
8696 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000));
David Benjamin5697a922022-07-21 10:35:59 -07008697 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), 16u);
David Benjamin3f180b82022-05-09 17:45:18 -04008698 EXPECT_EQ(count_tickets(), 16u);
8699}
8700
David Benjamin955ef792022-06-13 13:16:43 -04008701TEST(SSLTest, CertSubjectsToStack) {
8702 const std::string kCert1 = R"(
8703-----BEGIN CERTIFICATE-----
8704MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
8705QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
8706dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
8707BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
8708dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
8709v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
8710HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
8711HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
8712BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
8713BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
8714-----END CERTIFICATE-----
8715)";
8716 const std::vector<uint8_t> kName1 = {
8717 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
8718 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
8719 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
8720 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
8721 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
8722 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
8723 const std::string kCert2 = R"(
8724-----BEGIN CERTIFICATE-----
8725MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE
8726ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg
8727Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y
8728aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3
8729DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c
8730oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j
87315x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh
8732TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
8733CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0
87344nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB
8735gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y
8736rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU
8737xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==
8738-----END CERTIFICATE-----
8739)";
8740 const std::vector<uint8_t> kName2 = {
8741 0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a,
8742 0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c,
8743 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30,
8744 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61,
8745 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
8746
8747 const struct {
8748 std::vector<std::vector<uint8_t>> existing;
8749 std::string pem;
8750 std::vector<std::vector<uint8_t>> expected;
8751 } kTests[] = {
8752 // Do nothing.
8753 {{}, "", {}},
8754 // Append to an empty list, skipping duplicates.
8755 {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}},
8756 // One of the names was already present.
8757 {{kName1}, kCert1 + kCert2, {kName1, kName2}},
8758 // Both names were already present.
8759 {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}},
8760 // Preserve existing duplicates.
8761 {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}},
8762 };
8763 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
8764 SCOPED_TRACE(i);
8765 const auto &t = kTests[i];
8766
8767 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
8768 ASSERT_TRUE(stack);
8769 for (const auto& name : t.existing) {
8770 const uint8_t *inp = name.data();
8771 bssl::UniquePtr<X509_NAME> name_obj(
8772 d2i_X509_NAME(nullptr, &inp, name.size()));
8773 ASSERT_TRUE(name_obj);
8774 EXPECT_EQ(inp, name.data() + name.size());
8775 ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj)));
8776 }
8777
8778 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(t.pem.data(), t.pem.size()));
8779 ASSERT_TRUE(bio);
8780 ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get()));
8781
8782 // The function should have left |stack|'s comparison function alone.
8783 EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr));
8784
8785 std::vector<std::vector<uint8_t>> expected = t.expected, result;
8786 for (X509_NAME *name : stack.get()) {
8787 uint8_t *der = nullptr;
8788 int der_len = i2d_X509_NAME(name, &der);
8789 ASSERT_GE(der_len, 0);
8790 result.push_back(std::vector<uint8_t>(der, der + der_len));
8791 OPENSSL_free(der);
8792 }
8793
8794 // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a
8795 // well-defined order.
8796 std::sort(expected.begin(), expected.end());
8797 std::sort(result.begin(), result.end());
8798 EXPECT_EQ(result, expected);
8799 }
8800}
8801
David Benjamin4da5a942022-08-02 14:39:44 -07008802TEST(SSLTest, EmptyClientCAList) {
David Benjamin0ff377a2024-02-03 09:47:19 -05008803 if (SkipTempFileTests()) {
8804 GTEST_SKIP();
8805 }
8806
8807 TemporaryFile empty;
8808 ASSERT_TRUE(empty.Init());
David Benjamin4da5a942022-08-02 14:39:44 -07008809 bssl::UniquePtr<STACK_OF(X509_NAME)> names(
David Benjamin0ff377a2024-02-03 09:47:19 -05008810 SSL_load_client_CA_file(empty.path().c_str()));
David Benjamin4da5a942022-08-02 14:39:44 -07008811 EXPECT_FALSE(names);
8812}
David Benjamin4da5a942022-08-02 14:39:44 -07008813
David Benjaminb95c7e52022-07-22 16:28:22 -07008814TEST(SSLTest, EmptyWriteBlockedOnHandshakeData) {
8815 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8816 bssl::UniquePtr<SSL_CTX> server_ctx =
8817 CreateContextWithTestCertificate(TLS_method());
8818 ASSERT_TRUE(client_ctx);
8819 ASSERT_TRUE(server_ctx);
8820 // Configure only TLS 1.3. This test requires post-handshake NewSessionTicket.
8821 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
8822 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
8823
8824 // Connect a client and server with tiny buffer between the two.
8825 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
8826 server(SSL_new(server_ctx.get()));
8827 ASSERT_TRUE(client);
8828 ASSERT_TRUE(server);
8829 SSL_set_connect_state(client.get());
8830 SSL_set_accept_state(server.get());
8831 BIO *bio1, *bio2;
8832 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
8833 SSL_set_bio(client.get(), bio1, bio1);
8834 SSL_set_bio(server.get(), bio2, bio2);
8835 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
8836
8837 // We defer NewSessionTicket to the first write, so the server has a pending
8838 // NewSessionTicket. See https://boringssl-review.googlesource.com/34948. This
8839 // means an empty write will flush the ticket. However, the transport only
8840 // allows one byte through, so this will fail with |SSL_ERROR_WANT_WRITE|.
8841 int ret = SSL_write(server.get(), nullptr, 0);
8842 ASSERT_EQ(ret, -1);
8843 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8844
8845 // Attempting to write non-zero data should not trip |SSL_R_BAD_WRITE_RETRY|.
8846 const uint8_t kData[] = {'h', 'e', 'l', 'l', 'o'};
8847 ret = SSL_write(server.get(), kData, sizeof(kData));
8848 ASSERT_EQ(ret, -1);
8849 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8850
8851 // Byte by byte, the data should eventually get through.
8852 uint8_t buf[sizeof(kData)];
8853 for (;;) {
8854 ret = SSL_read(client.get(), buf, sizeof(buf));
8855 ASSERT_EQ(ret, -1);
8856 ASSERT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ);
8857
8858 ret = SSL_write(server.get(), kData, sizeof(kData));
8859 if (ret > 0) {
8860 ASSERT_EQ(ret, 5);
8861 break;
8862 }
8863 ASSERT_EQ(ret, -1);
8864 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8865 }
8866
8867 ret = SSL_read(client.get(), buf, sizeof(buf));
8868 ASSERT_EQ(ret, static_cast<int>(sizeof(kData)));
8869 ASSERT_EQ(Bytes(buf, ret), Bytes(kData));
8870}
8871
David Benjamin5cb597e2022-07-27 18:34:39 -07008872// Test that |SSL_ERROR_SYSCALL| continues to work after a close_notify.
8873TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
8874 // Make a custom |BIO| where writes fail, but without pushing to the error
8875 // queue.
8876 bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
8877 ASSERT_TRUE(method);
8878 BIO_meth_set_create(method.get(), [](BIO *b) -> int {
8879 BIO_set_init(b, 1);
8880 return 1;
8881 });
8882 static bool write_failed = false;
8883 BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
8884 // Fail the operation and don't add to the error queue.
8885 write_failed = true;
8886 return -1;
8887 });
8888 bssl::UniquePtr<BIO> wbio_silent_error(BIO_new(method.get()));
8889 ASSERT_TRUE(wbio_silent_error);
8890
8891 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8892 bssl::UniquePtr<SSL_CTX> server_ctx =
8893 CreateContextWithTestCertificate(TLS_method());
8894 ASSERT_TRUE(client_ctx);
8895 ASSERT_TRUE(server_ctx);
8896 bssl::UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05008897 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamin5cb597e2022-07-27 18:34:39 -07008898 server_ctx.get()));
8899
8900 // Replace the write |BIO| with |wbio_silent_error|.
8901 SSL_set0_wbio(client.get(), wbio_silent_error.release());
8902
8903 // Writes should fail. There is nothing in the error queue, so
8904 // |SSL_ERROR_SYSCALL| indicates the caller needs to check out-of-band.
8905 const uint8_t data[1] = {0};
8906 int ret = SSL_write(client.get(), data, sizeof(data));
8907 EXPECT_EQ(ret, -1);
8908 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8909 EXPECT_TRUE(write_failed);
8910 write_failed = false;
8911
8912 // Send a close_notify from the server. It should return 0 because
8913 // close_notify was sent, but not received. Confusingly, this is a success
8914 // output for |SSL_shutdown|'s API.
8915 EXPECT_EQ(SSL_shutdown(server.get()), 0);
8916
8917 // Read the close_notify on the client.
8918 uint8_t buf[1];
8919 ret = SSL_read(client.get(), buf, sizeof(buf));
8920 EXPECT_EQ(ret, 0);
8921 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
8922
David Benjaminebd8b892022-07-27 18:41:51 -07008923 // Further calls to |SSL_read| continue to report |SSL_ERROR_ZERO_RETURN|.
8924 ret = SSL_read(client.get(), buf, sizeof(buf));
8925 EXPECT_EQ(ret, 0);
8926 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
8927
David Benjamin5cb597e2022-07-27 18:34:39 -07008928 // Although the client has seen close_notify, it should continue to report
8929 // |SSL_ERROR_SYSCALL| when its writes fail.
8930 ret = SSL_write(client.get(), data, sizeof(data));
8931 EXPECT_EQ(ret, -1);
8932 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8933 EXPECT_TRUE(write_failed);
8934 write_failed = false;
David Benjaminebd8b892022-07-27 18:41:51 -07008935
8936 // Cause |BIO_write| to fail with a return value of zero instead.
8937 // |SSL_get_error| should not misinterpret this as a close_notify.
8938 //
8939 // This is not actually a correct implementation of |BIO_write|, but the rest
8940 // of the code treats zero from |BIO_write| as an error, so ensure it does so
8941 // correctly. Fixing https://crbug.com/boringssl/503 will make this case moot.
8942 BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
8943 write_failed = true;
8944 return 0;
8945 });
8946 ret = SSL_write(client.get(), data, sizeof(data));
8947 EXPECT_EQ(ret, 0);
8948 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8949 EXPECT_TRUE(write_failed);
8950 write_failed = false;
David Benjamin5cb597e2022-07-27 18:34:39 -07008951}
8952
David Benjamin401137f2022-07-28 10:27:47 -07008953// Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving
8954// a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|.
8955TEST(SSLTest, QuietShutdown) {
8956 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8957 bssl::UniquePtr<SSL_CTX> server_ctx =
8958 CreateContextWithTestCertificate(TLS_method());
8959 ASSERT_TRUE(client_ctx);
8960 ASSERT_TRUE(server_ctx);
8961 SSL_CTX_set_quiet_shutdown(server_ctx.get(), 1);
8962 bssl::UniquePtr<SSL> client, server;
David Benjaminf7d37fb2023-02-04 19:45:04 -05008963 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamin401137f2022-07-28 10:27:47 -07008964 server_ctx.get()));
8965
8966 // Quiet shutdown is enabled, so |SSL_shutdown| on the server should
8967 // immediately return that bidirectional shutdown "completed".
8968 EXPECT_EQ(SSL_shutdown(server.get()), 1);
8969
8970 // Shut down writes so the client gets an EOF.
8971 EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(server.get())));
8972
8973 // Confirm no close notify was actually sent. Client reads should report a
8974 // transport EOF, not a close_notify. (Both have zero return, but
8975 // |SSL_get_error| is different.)
8976 char buf[1];
8977 int ret = SSL_read(client.get(), buf, sizeof(buf));
8978 EXPECT_EQ(ret, 0);
8979 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8980
8981 // The server believes bidirectional shutdown completed, so reads should
8982 // replay the (simulated) close_notify.
8983 ret = SSL_read(server.get(), buf, sizeof(buf));
8984 EXPECT_EQ(ret, 0);
8985 EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_ZERO_RETURN);
8986}
8987
David Benjamin3a1b7302022-11-29 18:44:46 -05008988TEST(SSLTest, InvalidSignatureAlgorithm) {
8989 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8990 ASSERT_TRUE(ctx);
8991
8992 static const uint16_t kInvalidPrefs[] = {1234};
8993 EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs(
8994 ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs)));
8995 EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs(
8996 ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs)));
8997
8998 static const uint16_t kDuplicatePrefs[] = {SSL_SIGN_RSA_PKCS1_SHA256,
8999 SSL_SIGN_RSA_PKCS1_SHA256};
9000 EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs(
9001 ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs)));
9002 EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs(
9003 ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs)));
9004}
9005
David Benjamin6cf98202023-05-26 22:03:30 -04009006TEST(SSLTest, InvalidGroups) {
9007 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
9008 ASSERT_TRUE(ctx);
9009
9010 static const uint16_t kInvalidIDs[] = {1234};
9011 EXPECT_FALSE(SSL_CTX_set1_group_ids(
9012 ctx.get(), kInvalidIDs, OPENSSL_ARRAY_SIZE(kInvalidIDs)));
9013
9014 // This is a valid NID, but it is not a valid group.
9015 static const int kInvalidNIDs[] = {NID_rsaEncryption};
9016 EXPECT_FALSE(SSL_CTX_set1_groups(
9017 ctx.get(), kInvalidNIDs, OPENSSL_ARRAY_SIZE(kInvalidNIDs)));
9018}
9019
David Benjamina972b782023-05-05 10:22:43 -04009020TEST(SSLTest, NameLists) {
9021 struct {
9022 size_t (*func)(const char **, size_t);
9023 std::vector<std::string> expected;
9024 } kTests[] = {
9025 {SSL_get_all_version_names, {"TLSv1.3", "DTLSv1.2", "unknown"}},
9026 {SSL_get_all_standard_cipher_names,
9027 {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256"}},
9028 {SSL_get_all_cipher_names,
9029 {"ECDHE-ECDSA-AES128-GCM-SHA256", "TLS_AES_128_GCM_SHA256", "(NONE)"}},
David Benjamin335523a2023-05-26 21:55:56 -04009030 {SSL_get_all_group_names, {"P-256", "X25519"}},
David Benjamina972b782023-05-05 10:22:43 -04009031 {SSL_get_all_signature_algorithm_names,
9032 {"rsa_pkcs1_sha256", "ecdsa_secp256r1_sha256", "ecdsa_sha256"}},
9033 };
9034 for (const auto &t : kTests) {
9035 size_t num = t.func(nullptr, 0);
9036 EXPECT_GT(num, 0u);
9037
9038 std::vector<const char*> list(num);
9039 EXPECT_EQ(num, t.func(list.data(), list.size()));
9040
9041 // Check the expected values are in the list.
9042 for (const auto &s : t.expected) {
9043 EXPECT_NE(list.end(), std::find(list.begin(), list.end(), s))
9044 << "Could not find " << s;
9045 }
9046
9047 // Passing in a larger buffer should leave excess space alone.
9048 std::vector<const char *> list2(num + 1, "placeholder");
9049 EXPECT_EQ(num, t.func(list2.data(), list2.size()));
9050 for (size_t i = 0; i < num; i++) {
9051 EXPECT_STREQ(list[i], list2[i]);
9052 }
9053 EXPECT_STREQ(list2.back(), "placeholder");
9054
9055 // Passing in a shorter buffer should truncate the list.
9056 for (size_t l = 0; l < num; l++) {
9057 SCOPED_TRACE(l);
9058 list2.resize(l);
9059 EXPECT_EQ(num, t.func(list2.data(), list2.size()));
9060 for (size_t i = 0; i < l; i++) {
9061 EXPECT_STREQ(list[i], list2[i]);
9062 }
9063 }
9064 }
9065}
9066
David Benjamin4fe29eb2024-02-13 22:58:39 -05009067// Test that it is possible for the certificate to be configured on a mix of
9068// SSL_CTX and SSL. This ensures that we do not inadvertently overshare objects
9069// in SSL_new.
9070TEST(SSLTest, MixContextAndConnection) {
9071 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
9072 ASSERT_TRUE(ctx);
9073 bssl::UniquePtr<X509> cert = GetTestCertificate();
9074 ASSERT_TRUE(cert);
9075 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
9076 ASSERT_TRUE(key);
9077
9078 // Configure the certificate, but not the private key, on the context.
9079 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
9080
9081 bssl::UniquePtr<SSL> ssl1(SSL_new(ctx.get()));
9082 ASSERT_TRUE(ssl1.get());
9083 bssl::UniquePtr<SSL> ssl2(SSL_new(ctx.get()));
9084 ASSERT_TRUE(ssl2.get());
9085
9086 // There is no private key configured yet.
9087 EXPECT_FALSE(SSL_CTX_get0_privatekey(ctx.get()));
9088 EXPECT_FALSE(SSL_get_privatekey(ssl1.get()));
9089 EXPECT_FALSE(SSL_get_privatekey(ssl2.get()));
9090
9091 // Configuring the private key on |ssl1| works.
9092 ASSERT_TRUE(SSL_use_PrivateKey(ssl1.get(), key.get()));
9093 EXPECT_TRUE(SSL_get_privatekey(ssl1.get()));
9094
9095 // It does not impact the other connection or the context.
9096 EXPECT_FALSE(SSL_CTX_get0_privatekey(ctx.get()));
9097 EXPECT_FALSE(SSL_get_privatekey(ssl2.get()));
9098}
9099
David Benjamina6e2be42024-02-21 22:59:16 -05009100// Test that the server handshake cleanly fails if it had no certificate
9101// configured, at all versions.
9102TEST_P(SSLVersionTest, NoCertOrKey) {
9103 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
9104 ASSERT_TRUE(cert);
9105 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
9106 ASSERT_TRUE(key);
9107 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
9108 ASSERT_TRUE(intermediate);
9109 bssl::UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
9110 ASSERT_TRUE(chain);
9111 ASSERT_TRUE(bssl::PushToStack(chain.get(), std::move(intermediate)));
9112
9113 const struct {
9114 bool has_cert;
9115 bool has_key;
9116 bool has_chain;
9117 } kTests[] = {
9118 // If nothing is configured, there is unambiguously no certificate.
9119 {/*has_cert=*/false, /*has_key=*/false, /*has_chain=*/false},
9120
9121 // If only one of the key and certificate is configured, it is still treated
9122 // as if there is no certificate.
9123 {/*has_cert=*/true, /*has_key=*/false, /*has_chain=*/false},
9124 {/*has_cert=*/false, /*has_key=*/true, /*has_chain=*/false},
9125
9126 // The key and intermediates may be configured, but without a leaf there is
9127 // no certificate. This case is interesting because we internally store the
9128 // chain with a somewhat fragile null fist entry.
9129 {/*has_cert=*/false, /*has_key=*/true, /*has_chain=*/true},
9130 };
9131 for (const auto &t : kTests) {
9132 SCOPED_TRACE(testing::Message() << "has_cert = " << t.has_cert);
9133 SCOPED_TRACE(testing::Message() << "has_key = " << t.has_key);
9134 SCOPED_TRACE(testing::Message() << "has_chain = " << t.has_chain);
9135 for (bool client : {false, true}) {
9136 SCOPED_TRACE(testing::Message() << "client = " << client);
9137
9138 EXPECT_NO_FATAL_FAILURE(ResetContexts());
9139 if (client) {
9140 // Request client certificates from the server.
9141 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
9142 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed,
9143 nullptr);
9144 } else {
9145 // Recreate the server context. ResetContexts automatically adds server
9146 // certificates.
9147 server_ctx_ = CreateContext();
9148 ASSERT_TRUE(server_ctx_);
9149 }
9150
9151 SSL_CTX *ctx = client ? client_ctx_.get() : server_ctx_.get();
9152 if (t.has_cert) {
9153 ASSERT_TRUE(SSL_CTX_use_certificate(ctx, cert.get()));
9154 }
9155 if (t.has_key) {
9156 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx, key.get()));
9157 }
9158 if (t.has_chain) {
9159 ASSERT_TRUE(SSL_CTX_set1_chain(ctx, chain.get()));
9160 }
9161
9162 // In each of these cases, |SSL_CTX_check_private_key| should report the
9163 // certificate was not configured.
9164 EXPECT_FALSE(SSL_CTX_check_private_key(ctx));
9165 ERR_clear_error();
9166
9167 if (client) {
9168 // The client should cleanly handshake without asserting a certificate.
9169 EXPECT_TRUE(Connect());
9170 EXPECT_FALSE(SSL_get0_peer_certificates(server_.get()));
9171 } else {
9172 // Servers cannot be anonymous. The connection should fail.
9173 EXPECT_FALSE(Connect());
9174 // Depending on the TLS version, this should either appear as
9175 // NO_SHARED_CIPHER (TLS 1.2) or NO_CERTIFICATE_SET (TLS 1.3).
9176 uint32_t err = ERR_get_error();
9177 if (!ErrorEquals(err, ERR_LIB_SSL, SSL_R_NO_SHARED_CIPHER)) {
9178 EXPECT_TRUE(ErrorEquals(err, ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET));
9179 }
9180 }
9181 }
9182 }
9183}
9184
Martin Kreichgauer72912d22017-08-04 12:06:43 -07009185} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07009186BSSL_NAMESPACE_END