blob: f939bfe0a295930cbd82f8f1c7cb9cb02aac3088 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
Steven Valdezc8e0f902018-07-14 11:23:01 -040020#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040021#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050022#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040023#include <vector>
24
David Benjamin96628432017-01-19 19:05:47 -050025#include <gtest/gtest.h>
26
David Benjamin0e7dbd52019-05-15 16:01:18 -040027#include <openssl/aead.h>
David Benjamin751e8892014-10-19 00:59:36 -040028#include <openssl/base64.h>
29#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040030#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040031#include <openssl/crypto.h>
Daniel McArdle00e434d2021-02-18 11:47:18 -050032#include <openssl/curve25519.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040033#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040034#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050035#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040036#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040038#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050039#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040040
Steven Valdez87eab492016-06-27 16:34:59 -040041#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040042#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020043#include "../crypto/test/test_util.h"
44
David Benjamin721e8b72016-08-03 13:13:17 -040045#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040046// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040047OPENSSL_MSVC_PRAGMA(warning(push, 3))
48#include <winsock2.h>
49OPENSSL_MSVC_PRAGMA(warning(pop))
50#else
51#include <sys/time.h>
52#endif
53
David Benjamin5b33eff2018-09-22 16:52:48 -070054#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040055#include <thread>
56#endif
57
David Benjamin1d77e562015-03-22 17:22:08 -040058
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070059BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070060
61namespace {
62
Martin Kreichgauer1a663262017-08-16 14:54:04 -070063#define TRACED_CALL(code) \
64 do { \
65 SCOPED_TRACE("<- called from here"); \
66 code; \
67 if (::testing::Test::HasFatalFailure()) { \
68 return; \
69 } \
70 } while (false)
71
Martin Kreichgauer72912d22017-08-04 12:06:43 -070072struct VersionParam {
73 uint16_t version;
74 enum { is_tls, is_dtls } ssl_method;
75 const char name[8];
76};
77
78static const size_t kTicketKeyLen = 48;
79
80static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070081 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
82 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
83 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070084 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070085 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
86 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
87};
88
David Benjamin1d77e562015-03-22 17:22:08 -040089struct ExpectedCipher {
90 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040091 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040092};
David Benjaminbb0a17c2014-09-20 15:35:39 -040093
David Benjamin1d77e562015-03-22 17:22:08 -040094struct CipherTest {
95 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040096 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050097 // The list of expected ciphers, in order.
98 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080099 // True if this cipher list should fail in strict mode.
100 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400101};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400102
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100103struct CurveTest {
104 // The rule string to apply.
105 const char *rule;
106 // The list of expected curves, in order.
107 std::vector<uint16_t> expected;
108};
109
Steven Valdezc8e0f902018-07-14 11:23:01 -0400110template <typename T>
111class UnownedSSLExData {
112 public:
113 UnownedSSLExData() {
114 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
115 }
116
117 T *Get(const SSL *ssl) {
118 return index_ < 0 ? nullptr
119 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
120 }
121
122 bool Set(SSL *ssl, T *t) {
123 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
124 }
125
126 private:
127 int index_;
128};
129
David Benjaminfb974e62015-12-16 19:34:22 -0500130static const CipherTest kCipherTests[] = {
131 // Selecting individual ciphers should work.
132 {
133 "ECDHE-ECDSA-CHACHA20-POLY1305:"
134 "ECDHE-RSA-CHACHA20-POLY1305:"
135 "ECDHE-ECDSA-AES128-GCM-SHA256:"
136 "ECDHE-RSA-AES128-GCM-SHA256",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500139 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500140 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
142 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800143 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500144 },
145 // + reorders selected ciphers to the end, keeping their relative order.
146 {
147 "ECDHE-ECDSA-CHACHA20-POLY1305:"
148 "ECDHE-RSA-CHACHA20-POLY1305:"
149 "ECDHE-ECDSA-AES128-GCM-SHA256:"
150 "ECDHE-RSA-AES128-GCM-SHA256:"
151 "+aRSA",
152 {
153 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500156 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
157 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800158 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500159 },
160 // ! banishes ciphers from future selections.
161 {
162 "!aRSA:"
163 "ECDHE-ECDSA-CHACHA20-POLY1305:"
164 "ECDHE-RSA-CHACHA20-POLY1305:"
165 "ECDHE-ECDSA-AES128-GCM-SHA256:"
166 "ECDHE-RSA-AES128-GCM-SHA256",
167 {
168 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500169 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
170 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800171 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500172 },
173 // Multiple masks can be ANDed in a single rule.
174 {
175 "kRSA+AESGCM+AES128",
176 {
177 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
178 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800179 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500180 },
181 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700182 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500183 // ECDHE_RSA.
184 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700185 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700186 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500187 "AESGCM+AES128+aRSA",
188 {
189 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500190 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
191 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800192 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500193 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800194 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500195 {
196 "ECDHE-ECDSA-CHACHA20-POLY1305:"
197 "ECDHE-RSA-CHACHA20-POLY1305:"
198 "ECDHE-ECDSA-AES128-GCM-SHA256:"
199 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800200 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500201 {
202 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500203 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500204 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
205 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
206 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800207 true,
208 },
209 // Unknown selectors are no-ops, except in strict mode.
210 {
211 "ECDHE-ECDSA-CHACHA20-POLY1305:"
212 "ECDHE-RSA-CHACHA20-POLY1305:"
213 "ECDHE-ECDSA-AES128-GCM-SHA256:"
214 "ECDHE-RSA-AES128-GCM-SHA256:"
215 "-BOGUS2:+BOGUS3:!BOGUS4",
216 {
217 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
218 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
219 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
221 },
222 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500223 },
224 // Square brackets specify equi-preference groups.
225 {
226 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
227 "[ECDHE-RSA-CHACHA20-POLY1305]:"
228 "ECDHE-RSA-AES128-GCM-SHA256",
229 {
230 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500231 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800232 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500233 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
234 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800235 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500236 },
David Benjamin6fff3862017-06-21 21:07:04 -0400237 // Standard names may be used instead of OpenSSL names.
238 {
239 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400240 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400241 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
242 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
243 {
244 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
245 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
246 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
247 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
248 },
249 false,
250 },
David Benjaminfb974e62015-12-16 19:34:22 -0500251 // @STRENGTH performs a stable strength-sort of the selected ciphers and
252 // only the selected ciphers.
253 {
254 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700255 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400256 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500257 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700258 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500259 // Select ECDHE ones and sort them by strength. Ties should resolve
260 // based on the order above.
261 "kECDHE:@STRENGTH:-ALL:"
262 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
263 // by strength. Then RSA, backwards by strength.
264 "aRSA",
265 {
266 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
267 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500268 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500269 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
270 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
271 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800272 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500273 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400274 // Additional masks after @STRENGTH get silently discarded.
275 //
276 // TODO(davidben): Make this an error. If not silently discarded, they get
277 // interpreted as + opcodes which are very different.
278 {
279 "ECDHE-RSA-AES128-GCM-SHA256:"
280 "ECDHE-RSA-AES256-GCM-SHA384:"
281 "@STRENGTH+AES256",
282 {
283 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
284 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
285 },
286 false,
287 },
288 {
289 "ECDHE-RSA-AES128-GCM-SHA256:"
290 "ECDHE-RSA-AES256-GCM-SHA384:"
291 "@STRENGTH+AES256:"
292 "ECDHE-RSA-CHACHA20-POLY1305",
293 {
294 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
295 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
296 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
297 },
298 false,
299 },
David Benjaminfb974e62015-12-16 19:34:22 -0500300 // Exact ciphers may not be used in multi-part rules; they are treated
301 // as unknown aliases.
302 {
303 "ECDHE-ECDSA-AES128-GCM-SHA256:"
304 "ECDHE-RSA-AES128-GCM-SHA256:"
305 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
306 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
307 {
308 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
309 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
310 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800311 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500312 },
313 // SSLv3 matches everything that existed before TLS 1.2.
314 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400315 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500316 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400317 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500318 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800319 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500320 },
321 // TLSv1.2 matches everything added in TLS 1.2.
322 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400323 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500324 {
325 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
326 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800327 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500328 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800329 // The two directives have no intersection. But each component is valid, so
330 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500331 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400332 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500333 {
334 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400335 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500336 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800337 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500338 },
Adam Langley22df6912017-07-25 12:27:37 -0700339 // Spaces, semi-colons and commas are separators.
340 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400341 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700342 {
343 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400344 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700345 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400346 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700347 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
348 },
349 // …but not in strict mode.
350 true,
351 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400352};
353
354static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400355 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400356 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
357 "RSA]",
358 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400360 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400361 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400363 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 "",
365 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400366 // COMPLEMENTOFDEFAULT is empty.
367 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400368 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400369 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400370 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400371 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
372 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
373 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
374 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700375 // Opcode supplied, but missing selector.
376 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700377 // Spaces are forbidden in equal-preference groups.
378 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400379};
380
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700381static const char *kMustNotIncludeNull[] = {
382 "ALL",
383 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500384 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700385 "FIPS",
386 "SHA",
387 "SHA1",
388 "RSA",
389 "SSLv3",
390 "TLSv1",
391 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700392};
393
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100394static const CurveTest kCurveTests[] = {
395 {
396 "P-256",
397 { SSL_CURVE_SECP256R1 },
398 },
399 {
Adam Langley7b935932018-11-12 13:53:42 -0800400 "P-256:CECPQ2",
401 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
402 },
403
404 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100405 "P-256:P-384:P-521:X25519",
406 {
407 SSL_CURVE_SECP256R1,
408 SSL_CURVE_SECP384R1,
409 SSL_CURVE_SECP521R1,
410 SSL_CURVE_X25519,
411 },
412 },
David Benjamin6dda1662017-11-02 20:44:26 -0400413 {
414 "prime256v1:secp384r1:secp521r1:x25519",
415 {
416 SSL_CURVE_SECP256R1,
417 SSL_CURVE_SECP384R1,
418 SSL_CURVE_SECP521R1,
419 SSL_CURVE_X25519,
420 },
421 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100422};
423
424static const char *kBadCurvesLists[] = {
425 "",
426 ":",
427 "::",
428 "P-256::X25519",
429 "RSA:P-256",
430 "P-256:RSA",
431 "X25519:P-256:",
432 ":X25519:P-256",
433};
434
David Benjamin70dbf042017-08-08 18:51:37 -0400435static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400436 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400437 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400438 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
439 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
440 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
441 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400442 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400443 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444 }
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400446 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400447 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448 }
David Benjamine11726a2017-04-23 12:14:28 -0400449 ret += SSL_CIPHER_get_name(cipher);
450 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400451 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400452 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400453 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400454 }
455 }
David Benjamine11726a2017-04-23 12:14:28 -0400456 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400457}
458
David Benjamin70dbf042017-08-08 18:51:37 -0400459static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400460 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400461 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
462 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400463 return false;
David Benjamin65226252015-02-05 16:49:47 -0500464 }
465
David Benjamine11726a2017-04-23 12:14:28 -0400466 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400467 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400468 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400469 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400470 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400471 }
472 }
473
David Benjamin1d77e562015-03-22 17:22:08 -0400474 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400475}
476
Daniel McArdleff746c12019-09-16 12:35:05 -0400477TEST(GrowableArrayTest, Resize) {
478 GrowableArray<size_t> array;
479 ASSERT_TRUE(array.empty());
480 EXPECT_EQ(array.size(), 0u);
481
482 ASSERT_TRUE(array.Push(42));
483 ASSERT_TRUE(!array.empty());
484 EXPECT_EQ(array.size(), 1u);
485
486 // Force a resize operation to occur
487 for (size_t i = 0; i < 16; i++) {
488 ASSERT_TRUE(array.Push(i + 1));
489 }
490
491 EXPECT_EQ(array.size(), 17u);
492
493 // Verify that expected values are still contained in array
494 for (size_t i = 0; i < array.size(); i++) {
495 EXPECT_EQ(array[i], i == 0 ? 42 : i);
496 }
497}
498
499TEST(GrowableArrayTest, MoveConstructor) {
500 GrowableArray<size_t> array;
501 for (size_t i = 0; i < 100; i++) {
502 ASSERT_TRUE(array.Push(i));
503 }
504
505 GrowableArray<size_t> array_moved(std::move(array));
506 for (size_t i = 0; i < 100; i++) {
507 EXPECT_EQ(array_moved[i], i);
508 }
509}
510
511TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
512 // Representative example of a struct that contains a GrowableArray.
513 struct TagAndArray {
514 size_t tag;
515 GrowableArray<size_t> array;
516 };
517
518 GrowableArray<TagAndArray> array;
519 for (size_t i = 0; i < 100; i++) {
520 TagAndArray elem;
521 elem.tag = i;
522 for (size_t j = 0; j < i; j++) {
523 ASSERT_TRUE(elem.array.Push(j));
524 }
525 ASSERT_TRUE(array.Push(std::move(elem)));
526 }
527 EXPECT_EQ(array.size(), static_cast<size_t>(100));
528
529 GrowableArray<TagAndArray> array_moved(std::move(array));
530 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
531 size_t count = 0;
532 for (const TagAndArray &elem : array_moved) {
533 // Test the square bracket operator returns the same value as iteration.
534 EXPECT_EQ(&elem, &array_moved[count]);
535
536 EXPECT_EQ(elem.tag, count);
537 EXPECT_EQ(elem.array.size(), count);
538 for (size_t j = 0; j < count; j++) {
539 EXPECT_EQ(elem.array[j], j);
540 }
541 count++;
542 }
543}
544
David Benjamine11726a2017-04-23 12:14:28 -0400545TEST(SSLTest, CipherRules) {
546 for (const CipherTest &t : kCipherTests) {
547 SCOPED_TRACE(t.rule);
548 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
549 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700550
David Benjamine11726a2017-04-23 12:14:28 -0400551 // Test lax mode.
552 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400553 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400554 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400555 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400556
557 // Test strict mode.
558 if (t.strict_fail) {
559 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
560 } else {
561 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400562 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400563 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400564 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400565 }
566 }
567
David Benjaminfb974e62015-12-16 19:34:22 -0500568 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400569 SCOPED_TRACE(rule);
570 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
571 ASSERT_TRUE(ctx);
572
573 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400574 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400575 }
576
David Benjaminfb974e62015-12-16 19:34:22 -0500577 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400578 SCOPED_TRACE(rule);
579 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
580 ASSERT_TRUE(ctx);
581
582 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400583 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700584 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700585 }
586 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400587}
David Benjamin2e521212014-07-16 14:37:51 -0400588
David Benjamine11726a2017-04-23 12:14:28 -0400589TEST(SSLTest, CurveRules) {
590 for (const CurveTest &t : kCurveTests) {
591 SCOPED_TRACE(t.rule);
592 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
593 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100594
David Benjamine11726a2017-04-23 12:14:28 -0400595 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400596 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400597 for (size_t i = 0; i < t.expected.size(); i++) {
598 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100599 }
600 }
601
602 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400603 SCOPED_TRACE(rule);
604 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
605 ASSERT_TRUE(ctx);
606
607 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100608 ERR_clear_error();
609 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100610}
611
Adam Langley364f7a62016-12-12 10:51:00 -0800612// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700613static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800614 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700615 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
616 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
617 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
618 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
619 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
620 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
621 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
622 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
623 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
624 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
625 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
626 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
627 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
628 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
629 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
630 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
631 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
632 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
633 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
634 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
635 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
636 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
637 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
638 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
639 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
640 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
641 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
642 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
643 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800644 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700645
646// kCustomSession is a custom serialized SSL_SESSION generated by
647// filling in missing fields from |kOpenSSLSession|. This includes
648// providing |peer_sha256|, so |peer| is not serialized.
649static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400650 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700651 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400652 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
653 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
654 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
655 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
656 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
657 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700658
659// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
660static const char kBoringSSLSession[] =
661 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
662 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
663 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
664 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
665 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
666 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
667 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
668 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
669 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
670 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
671 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
672 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
673 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
674 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
675 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
676 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
677 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
678 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
679 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
680 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
681 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
682 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
683 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
684 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
685 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
686 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
687 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
688 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
689 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
690 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
691 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
692 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
693 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
694 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
695 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
696 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
697 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
698 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
699 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
700 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
701 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
702 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
703 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
704 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
705 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
706 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
707 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
708 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
709 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
710 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
711 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
712 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
713 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
714 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
715 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
716 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
717 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
718 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
719 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
720 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
721 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
722 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
723 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
724 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
725 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
726 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
727 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
728 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
729 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
730 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
731 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
732 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
733 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
734 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
735 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
736 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
737 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
738 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
739 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
740 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
741 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
742 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
743 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
744 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
745 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
746 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
747 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
748 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
749 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
750 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
751 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
752 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
753 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
754 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
755 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
756
757// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400758// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700759static const char kBadSessionExtraField[] =
760 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
761 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
762 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
763 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
764 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
765 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
766 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400767 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700768
769// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
770// the version of |kCustomSession| with 2.
771static const char kBadSessionVersion[] =
772 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
773 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
774 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
775 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
776 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
777 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
778 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
779 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
780
781// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
782// appended.
783static const char kBadSessionTrailingData[] =
784 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
785 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
786 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
787 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
788 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
789 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
790 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
791 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
792
David Benjamin1d77e562015-03-22 17:22:08 -0400793static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400794 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400795 if (!EVP_DecodedLength(&len, strlen(in))) {
796 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400797 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400798 }
799
David Benjamin1d77e562015-03-22 17:22:08 -0400800 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800801 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400802 strlen(in))) {
803 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400804 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400805 }
David Benjamin1d77e562015-03-22 17:22:08 -0400806 out->resize(len);
807 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400808}
809
David Benjamina486c6c2019-03-28 18:32:38 -0500810TEST(SSLTest, SessionEncoding) {
811 for (const char *input_b64 : {
812 kOpenSSLSession,
813 kCustomSession,
814 kBoringSSLSession,
815 }) {
816 SCOPED_TRACE(std::string(input_b64));
817 // Decode the input.
818 std::vector<uint8_t> input;
819 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400820
David Benjamina486c6c2019-03-28 18:32:38 -0500821 // Verify the SSL_SESSION decodes.
822 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
823 ASSERT_TRUE(ssl_ctx);
824 bssl::UniquePtr<SSL_SESSION> session(
825 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
826 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
827
828 // Verify the SSL_SESSION encoding round-trips.
829 size_t encoded_len;
830 bssl::UniquePtr<uint8_t> encoded;
831 uint8_t *encoded_raw;
832 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
833 << "SSL_SESSION_to_bytes failed";
834 encoded.reset(encoded_raw);
835 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
836 << "SSL_SESSION_to_bytes did not round-trip";
837
838 // Verify the SSL_SESSION also decodes with the legacy API.
839 const uint8_t *cptr = input.data();
840 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
841 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
842 EXPECT_EQ(cptr, input.data() + input.size());
843
844 // Verify the SSL_SESSION encoding round-trips via the legacy API.
845 int len = i2d_SSL_SESSION(session.get(), NULL);
846 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
847 ASSERT_EQ(static_cast<size_t>(len), input.size())
848 << "i2d_SSL_SESSION(NULL) returned invalid length";
849
850 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
851 ASSERT_TRUE(encoded);
852
853 uint8_t *ptr = encoded.get();
854 len = i2d_SSL_SESSION(session.get(), &ptr);
855 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
856 ASSERT_EQ(static_cast<size_t>(len), input.size())
857 << "i2d_SSL_SESSION(NULL) returned invalid length";
858 ASSERT_EQ(ptr, encoded.get() + input.size())
859 << "i2d_SSL_SESSION did not advance ptr correctly";
860 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
861 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400862 }
863
David Benjamina486c6c2019-03-28 18:32:38 -0500864 for (const char *input_b64 : {
865 kBadSessionExtraField,
866 kBadSessionVersion,
867 kBadSessionTrailingData,
868 }) {
869 SCOPED_TRACE(std::string(input_b64));
870 std::vector<uint8_t> input;
871 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400872
David Benjamina486c6c2019-03-28 18:32:38 -0500873 // Verify that the SSL_SESSION fails to decode.
874 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
875 ASSERT_TRUE(ssl_ctx);
876 bssl::UniquePtr<SSL_SESSION> session(
877 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
878 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
879 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400880 }
David Benjaminf297e022015-05-28 19:55:29 -0400881}
882
David Benjamin321fcdc2017-04-24 11:42:42 -0400883static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
884 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700885 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400886 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700887 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
888 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400889}
890
891TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800892 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400893 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
894 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
895 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700896 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
897 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
898 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500899}
900
David Benjamin348f0d82017-08-10 16:06:27 -0400901TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400902 static const struct {
903 int id;
904 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400905 int cipher_nid;
906 int digest_nid;
907 int kx_nid;
908 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400909 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400910 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400911 {
912 SSL3_CK_RSA_DES_192_CBC3_SHA,
913 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
914 NID_des_ede3_cbc,
915 NID_sha1,
916 NID_kx_rsa,
917 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400918 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400919 },
920 {
921 TLS1_CK_RSA_WITH_AES_128_SHA,
922 "TLS_RSA_WITH_AES_128_CBC_SHA",
923 NID_aes_128_cbc,
924 NID_sha1,
925 NID_kx_rsa,
926 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400927 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400928 },
929 {
930 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
931 "TLS_PSK_WITH_AES_256_CBC_SHA",
932 NID_aes_256_cbc,
933 NID_sha1,
934 NID_kx_psk,
935 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400936 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400937 },
938 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400939 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
940 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400941 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400942 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400943 NID_kx_ecdhe,
944 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400945 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400946 },
947 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400948 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
949 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400950 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400951 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400952 NID_kx_ecdhe,
953 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400954 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400955 },
956 {
957 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
958 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
959 NID_aes_128_gcm,
960 NID_undef,
961 NID_kx_ecdhe,
962 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400963 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400964 },
965 {
966 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
967 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
968 NID_aes_128_gcm,
969 NID_undef,
970 NID_kx_ecdhe,
971 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400972 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400973 },
974 {
975 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
976 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
977 NID_aes_256_gcm,
978 NID_undef,
979 NID_kx_ecdhe,
980 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400981 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400982 },
983 {
984 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
985 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
986 NID_aes_128_cbc,
987 NID_sha1,
988 NID_kx_ecdhe,
989 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400990 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400991 },
992 {
993 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
994 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
995 NID_chacha20_poly1305,
996 NID_undef,
997 NID_kx_ecdhe,
998 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400999 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001000 },
1001 {
1002 TLS1_CK_AES_256_GCM_SHA384,
1003 "TLS_AES_256_GCM_SHA384",
1004 NID_aes_256_gcm,
1005 NID_undef,
1006 NID_kx_any,
1007 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001008 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001009 },
1010 {
1011 TLS1_CK_AES_128_GCM_SHA256,
1012 "TLS_AES_128_GCM_SHA256",
1013 NID_aes_128_gcm,
1014 NID_undef,
1015 NID_kx_any,
1016 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001017 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001018 },
1019 {
1020 TLS1_CK_CHACHA20_POLY1305_SHA256,
1021 "TLS_CHACHA20_POLY1305_SHA256",
1022 NID_chacha20_poly1305,
1023 NID_undef,
1024 NID_kx_any,
1025 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001026 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001027 },
David Benjamin6fff3862017-06-21 21:07:04 -04001028 };
David Benjamin65226252015-02-05 16:49:47 -05001029
David Benjamin6fff3862017-06-21 21:07:04 -04001030 for (const auto &t : kTests) {
1031 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001032
1033 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1034 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001035 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1036
David Benjamine11726a2017-04-23 12:14:28 -04001037 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1038 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001039 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001040
1041 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1042 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1043 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1044 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001045 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001046 }
David Benjamin65226252015-02-05 16:49:47 -05001047}
1048
Steven Valdeza833c352016-11-01 13:39:36 -04001049// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1050// version and ticket length or nullptr on failure.
1051static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1052 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001053 std::vector<uint8_t> der;
1054 if (!DecodeBase64(&der, kOpenSSLSession)) {
1055 return nullptr;
1056 }
Adam Langley46db7af2017-02-01 15:49:37 -08001057
1058 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1059 if (!ssl_ctx) {
1060 return nullptr;
1061 }
David Benjaminaaef8332018-06-29 16:45:49 -04001062 // Use a garbage ticket.
1063 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001064 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001065 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001066 if (!session ||
1067 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1068 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001069 return nullptr;
1070 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001071 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001072#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001073 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001074#else
David Benjaminaaef8332018-06-29 16:45:49 -04001075 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001076#endif
David Benjamin422fe082015-07-21 22:03:43 -04001077 return session;
1078}
1079
David Benjaminafc64de2016-07-19 17:12:41 +02001080static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001081 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001082 if (!bio) {
1083 return false;
1084 }
1085 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001086 BIO_up_ref(bio.get());
1087 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001088 int ret = SSL_connect(ssl);
1089 if (ret > 0) {
1090 // SSL_connect should fail without a BIO to write to.
1091 return false;
1092 }
1093 ERR_clear_error();
1094
1095 const uint8_t *client_hello;
1096 size_t client_hello_len;
1097 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1098 return false;
1099 }
1100 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1101 return true;
1102}
1103
Steven Valdeza833c352016-11-01 13:39:36 -04001104// GetClientHelloLen creates a client SSL connection with the specified version
1105// and ticket length. It returns the length of the ClientHello, not including
1106// the record header, on success and zero on error.
1107static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1108 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001109 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001110 bssl::UniquePtr<SSL_SESSION> session =
1111 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001112 if (!ctx || !session) {
1113 return 0;
1114 }
Steven Valdeza833c352016-11-01 13:39:36 -04001115
1116 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001117 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001118 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001119 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001120 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001121 return 0;
1122 }
Steven Valdeza833c352016-11-01 13:39:36 -04001123
David Benjaminafc64de2016-07-19 17:12:41 +02001124 std::vector<uint8_t> client_hello;
1125 if (!GetClientHello(ssl.get(), &client_hello) ||
1126 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001127 return 0;
1128 }
Steven Valdeza833c352016-11-01 13:39:36 -04001129
David Benjaminafc64de2016-07-19 17:12:41 +02001130 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001131}
1132
David Benjamina486c6c2019-03-28 18:32:38 -05001133TEST(SSLTest, Padding) {
1134 struct PaddingVersions {
1135 uint16_t max_version, session_version;
1136 };
1137 static const PaddingVersions kPaddingVersions[] = {
1138 // Test the padding extension at TLS 1.2.
1139 {TLS1_2_VERSION, TLS1_2_VERSION},
1140 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1141 // will be no PSK binder after the padding extension.
1142 {TLS1_3_VERSION, TLS1_2_VERSION},
1143 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1144 // will be a PSK binder after the padding extension.
1145 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001146
David Benjamina486c6c2019-03-28 18:32:38 -05001147 };
David Benjamin422fe082015-07-21 22:03:43 -04001148
David Benjamina486c6c2019-03-28 18:32:38 -05001149 struct PaddingTest {
1150 size_t input_len, padded_len;
1151 };
1152 static const PaddingTest kPaddingTests[] = {
1153 // ClientHellos of length below 0x100 do not require padding.
1154 {0xfe, 0xfe},
1155 {0xff, 0xff},
1156 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1157 {0x100, 0x200},
1158 {0x123, 0x200},
1159 {0x1fb, 0x200},
1160 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1161 // padding extension takes a minimum of four bytes plus one required
1162 // content
1163 // byte. (To work around yet more server bugs, we avoid empty final
1164 // extensions.)
1165 {0x1fc, 0x201},
1166 {0x1fd, 0x202},
1167 {0x1fe, 0x203},
1168 {0x1ff, 0x204},
1169 // Finally, larger ClientHellos need no padding.
1170 {0x200, 0x200},
1171 {0x201, 0x201},
1172 };
David Benjamin422fe082015-07-21 22:03:43 -04001173
David Benjamina486c6c2019-03-28 18:32:38 -05001174 for (const PaddingVersions &versions : kPaddingVersions) {
1175 SCOPED_TRACE(versions.max_version);
1176 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001177
David Benjamina486c6c2019-03-28 18:32:38 -05001178 // Sample a baseline length.
1179 size_t base_len =
1180 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1181 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1182
1183 for (const PaddingTest &test : kPaddingTests) {
1184 SCOPED_TRACE(test.input_len);
1185 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1186
1187 size_t padded_len =
1188 GetClientHelloLen(versions.max_version, versions.session_version,
1189 1 + test.input_len - base_len);
1190 EXPECT_EQ(padded_len, test.padded_len)
1191 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001192 }
1193 }
David Benjamin422fe082015-07-21 22:03:43 -04001194}
1195
David Benjamin2f3958a2021-04-16 11:55:23 -04001196static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1197 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1198 if (!bio) {
1199 return nullptr;
1200 }
1201 return bssl::UniquePtr<X509>(
1202 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1203}
1204
1205static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1206 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1207 if (!bio) {
1208 return nullptr;
1209 }
1210 return bssl::UniquePtr<EVP_PKEY>(
1211 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1212}
1213
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001214static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001215 static const char kCertPEM[] =
1216 "-----BEGIN CERTIFICATE-----\n"
1217 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1218 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1219 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1220 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1221 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1222 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1223 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1224 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1225 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1226 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1227 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1228 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1229 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1230 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001231 return CertFromPEM(kCertPEM);
David Benjaminde942382016-02-11 12:02:01 -05001232}
1233
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001234static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001235 static const char kKeyPEM[] =
1236 "-----BEGIN RSA PRIVATE KEY-----\n"
1237 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1238 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1239 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1240 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1241 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1242 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1243 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1244 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1245 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1246 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1247 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1248 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1249 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1250 "-----END RSA PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001251 return KeyFromPEM(kKeyPEM);
David Benjaminde942382016-02-11 12:02:01 -05001252}
1253
David Benjamin9b2cdb72021-04-01 23:21:53 -04001254static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1255 const SSL_METHOD *method) {
1256 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1257 bssl::UniquePtr<X509> cert = GetTestCertificate();
1258 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1259 if (!ctx || !cert || !key ||
1260 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1261 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1262 return nullptr;
1263 }
1264 return ctx;
1265}
1266
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001267static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001268 static const char kCertPEM[] =
1269 "-----BEGIN CERTIFICATE-----\n"
1270 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1271 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1272 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1273 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1274 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1275 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1276 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1277 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1278 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1279 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1280 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001281 return CertFromPEM(kCertPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001282}
1283
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001284static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001285 static const char kKeyPEM[] =
1286 "-----BEGIN PRIVATE KEY-----\n"
1287 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1288 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1289 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1290 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001291 return KeyFromPEM(kKeyPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001292}
1293
Adam Langleyd04ca952017-02-28 11:26:51 -08001294static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1295 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1296 char *name, *header;
1297 uint8_t *data;
1298 long data_len;
1299 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1300 &data_len)) {
1301 return nullptr;
1302 }
1303 OPENSSL_free(name);
1304 OPENSSL_free(header);
1305
1306 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1307 CRYPTO_BUFFER_new(data, data_len, nullptr));
1308 OPENSSL_free(data);
1309 return ret;
1310}
1311
1312static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001313 static const char kCertPEM[] =
1314 "-----BEGIN CERTIFICATE-----\n"
1315 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1316 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1317 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1318 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1319 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1320 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1321 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1322 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1323 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1324 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1325 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1326 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1327 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1328 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1329 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1330 "1ngWZ7Ih\n"
1331 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001332 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001333}
1334
Adam Langleyd04ca952017-02-28 11:26:51 -08001335static bssl::UniquePtr<X509> X509FromBuffer(
1336 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1337 if (!buffer) {
1338 return nullptr;
1339 }
1340 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1341 return bssl::UniquePtr<X509>(
1342 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1343}
1344
1345static bssl::UniquePtr<X509> GetChainTestCertificate() {
1346 return X509FromBuffer(GetChainTestCertificateBuffer());
1347}
1348
1349static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001350 static const char kCertPEM[] =
1351 "-----BEGIN CERTIFICATE-----\n"
1352 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1353 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1354 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1355 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1356 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1357 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1358 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1359 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1360 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1361 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1362 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1363 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1364 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1365 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1366 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1367 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001368 return BufferFromPEM(kCertPEM);
1369}
1370
1371static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1372 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001373}
1374
1375static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1376 static const char kKeyPEM[] =
1377 "-----BEGIN PRIVATE KEY-----\n"
1378 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1379 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1380 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1381 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1382 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1383 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1384 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1385 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1386 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1387 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1388 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1389 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1390 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1391 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1392 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1393 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1394 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1395 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1396 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1397 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1398 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1399 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1400 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1401 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1402 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1403 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1404 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001405 return KeyFromPEM(kKeyPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001406}
1407
David Benjaminc79ae7a2017-08-29 16:09:44 -04001408// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1409// before configuring as a server.
1410TEST(SSLTest, ClientCAList) {
1411 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1412 ASSERT_TRUE(ctx);
1413 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1414 ASSERT_TRUE(ssl);
1415
1416 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1417 ASSERT_TRUE(name);
1418
1419 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1420 ASSERT_TRUE(name_dup);
1421
1422 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1423 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001424 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001425
1426 // |SSL_set_client_CA_list| takes ownership.
1427 SSL_set_client_CA_list(ssl.get(), stack.release());
1428
1429 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1430 ASSERT_TRUE(result);
1431 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1432 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1433}
1434
1435TEST(SSLTest, AddClientCA) {
1436 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1437 ASSERT_TRUE(ctx);
1438 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1439 ASSERT_TRUE(ssl);
1440
1441 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1442 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1443 ASSERT_TRUE(cert1 && cert2);
1444 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1445 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1446
1447 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1448
1449 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1450 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1451
1452 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1453 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1454 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1455 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1456
1457 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1458
1459 list = SSL_get_client_CA_list(ssl.get());
1460 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1461 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1462 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1463 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1464}
1465
Daniel McArdle00e434d2021-02-18 11:47:18 -05001466// kECHConfig contains a serialized ECHConfig value.
1467static const uint8_t kECHConfig[] = {
1468 // version
Steven Valdez94a63a52021-04-29 10:52:42 -04001469 0xfe, 0x0a,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001470 // length
Steven Valdez94a63a52021-04-29 10:52:42 -04001471 0x00, 0x43,
1472 // contents.config_id
1473 0x42,
1474 // contents.kem_id
1475 0x00, 0x20,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001476 // contents.public_key
1477 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1478 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1479 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001480 // contents.cipher_suites
1481 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1482 // contents.maximum_name_length
1483 0x00, 0x10,
Steven Valdez94a63a52021-04-29 10:52:42 -04001484 // contents.public_name
1485 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1486 0x6d, 0x70, 0x6c, 0x65,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001487 // contents.extensions
1488 0x00, 0x00};
1489
David Benjaminc3b373b2021-06-06 13:04:26 -04001490// kECHPublicKey is the public key encoded in |kECHConfig|.
1491static const uint8_t kECHPublicKey[X25519_PUBLIC_VALUE_LEN] = {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001492 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3, 0x6a,
1493 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1494 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c};
1495
David Benjaminc3b373b2021-06-06 13:04:26 -04001496// kECHPrivateKey is the X25519 private key corresponding to |kECHPublicKey|.
1497static const uint8_t kECHPrivateKey[X25519_PRIVATE_KEY_LEN] = {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001498 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1499 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1500 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1501
1502// MakeECHConfig serializes an ECHConfig and writes it to |*out| with the
1503// specified parameters. |cipher_suites| is a list of code points which should
1504// contain pairs of KDF and AEAD IDs.
Steven Valdez94a63a52021-04-29 10:52:42 -04001505bool MakeECHConfig(std::vector<uint8_t> *out, uint8_t config_id,
1506 uint16_t kem_id, Span<const uint8_t> public_key,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001507 Span<const uint16_t> cipher_suites,
1508 Span<const uint8_t> extensions) {
1509 bssl::ScopedCBB cbb;
1510 CBB contents, child;
1511 static const char kPublicName[] = "example.com";
1512 if (!CBB_init(cbb.get(), 64) ||
1513 !CBB_add_u16(cbb.get(), TLSEXT_TYPE_encrypted_client_hello) ||
1514 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001515 !CBB_add_u8(&contents, config_id) ||
1516 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001517 !CBB_add_u16_length_prefixed(&contents, &child) ||
1518 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001519 !CBB_add_u16_length_prefixed(&contents, &child)) {
1520 return false;
1521 }
1522 for (uint16_t cipher_suite : cipher_suites) {
1523 if (!CBB_add_u16(&child, cipher_suite)) {
1524 return false;
1525 }
1526 }
1527 if (!CBB_add_u16(&contents, strlen(kPublicName)) || // maximum_name_length
1528 !CBB_add_u16_length_prefixed(&contents, &child) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001529 !CBB_add_bytes(&child, reinterpret_cast<const uint8_t *>(kPublicName),
1530 strlen(kPublicName)) ||
1531 !CBB_add_u16_length_prefixed(&contents, &child) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001532 !CBB_add_bytes(&child, extensions.data(), extensions.size()) ||
1533 !CBB_flush(cbb.get())) {
1534 return false;
1535 }
1536
1537 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1538 return true;
1539}
1540
David Benjaminc3b373b2021-06-06 13:04:26 -04001541TEST(SSLTest, ECHKeys) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001542 // kWrongPrivateKey is an unrelated, but valid X25519 private key.
1543 const uint8_t kWrongPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1544 0xbb, 0xfe, 0x08, 0xf7, 0x31, 0xde, 0x9c, 0x8a, 0xf2, 0x06, 0x4a,
1545 0x18, 0xd7, 0x8b, 0x79, 0x31, 0xe2, 0x53, 0xdd, 0x63, 0x8f, 0x58,
1546 0x42, 0xda, 0x21, 0x0e, 0x61, 0x97, 0x29, 0xcc, 0x17, 0x71};
1547
1548 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1549 ASSERT_TRUE(ctx);
1550
David Benjaminc3b373b2021-06-06 13:04:26 -04001551 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1552 ASSERT_TRUE(keys);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001553
1554 // Adding an ECHConfig with the wrong private key is an error.
David Benjaminc3b373b2021-06-06 13:04:26 -04001555 ASSERT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
1556 sizeof(kECHConfig), kWrongPrivateKey,
1557 sizeof(kWrongPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001558 uint32_t err = ERR_get_error();
1559 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1560 EXPECT_EQ(SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH,
1561 ERR_GET_REASON(err));
1562 ERR_clear_error();
1563
1564 // Adding an ECHConfig with the matching private key succeeds.
David Benjaminc3b373b2021-06-06 13:04:26 -04001565 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
1566 sizeof(kECHConfig), kECHPrivateKey,
1567 sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001568
David Benjaminc3b373b2021-06-06 13:04:26 -04001569 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001570
1571 // Build a new config list and replace the old one on |ctx|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001572 bssl::UniquePtr<SSL_ECH_KEYS> next_keys(SSL_ECH_KEYS_new());
1573 ASSERT_TRUE(SSL_ECH_KEYS_add(next_keys.get(), /*is_retry_config=*/1,
1574 kECHConfig, sizeof(kECHConfig), kECHPrivateKey,
1575 sizeof(kECHPrivateKey)));
1576 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), next_keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001577}
1578
1579TEST(SSLTest, ECHServerConfigListTruncatedPublicKey) {
1580 std::vector<uint8_t> ech_config;
1581 ASSERT_TRUE(MakeECHConfig(
Steven Valdez94a63a52021-04-29 10:52:42 -04001582 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
David Benjaminc3b373b2021-06-06 13:04:26 -04001583 MakeConstSpan(kECHPublicKey, sizeof(kECHPublicKey) - 1),
David Benjaminf39c81d2021-05-03 18:39:46 -04001584 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001585 /*extensions=*/{}));
1586
1587 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1588 ASSERT_TRUE(ctx);
1589
David Benjaminc3b373b2021-06-06 13:04:26 -04001590 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1591 ASSERT_TRUE(keys);
1592 ASSERT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1593 ech_config.data(), ech_config.size(),
1594 kECHPrivateKey, sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001595
1596 uint32_t err = ERR_peek_error();
1597 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
David Benjamin1d58cd12021-05-04 15:24:24 -04001598 EXPECT_EQ(SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH,
1599 ERR_GET_REASON(err));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001600 ERR_clear_error();
1601}
1602
David Benjaminc3b373b2021-06-06 13:04:26 -04001603// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001604// has no retry configs.
1605TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
1606 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1607 ASSERT_TRUE(ctx);
1608
David Benjaminc3b373b2021-06-06 13:04:26 -04001609 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1610 ASSERT_TRUE(keys);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001611
1612 // Adding an ECHConfig with the matching private key succeeds.
David Benjaminc3b373b2021-06-06 13:04:26 -04001613 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, kECHConfig,
1614 sizeof(kECHConfig), kECHPrivateKey,
1615 sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001616
David Benjaminc3b373b2021-06-06 13:04:26 -04001617 ASSERT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001618 uint32_t err = ERR_peek_error();
1619 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1620 EXPECT_EQ(SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS, ERR_GET_REASON(err));
1621 ERR_clear_error();
1622
1623 // Add the same ECHConfig to the list, but this time mark it as a retry
1624 // config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001625 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
1626 sizeof(kECHConfig), kECHPrivateKey,
1627 sizeof(kECHPrivateKey)));
1628 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001629}
1630
1631// Test that the server APIs reject ECHConfigs with unsupported features.
1632TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001633 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1634 ASSERT_TRUE(keys);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001635
1636 // Unsupported versions are rejected.
1637 static const uint8_t kUnsupportedVersion[] = {0xff, 0xff, 0x00, 0x00};
David Benjaminc3b373b2021-06-06 13:04:26 -04001638 EXPECT_FALSE(SSL_ECH_KEYS_add(
1639 keys.get(), /*is_retry_config=*/1, kUnsupportedVersion,
1640 sizeof(kUnsupportedVersion), kECHPrivateKey, sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001641
1642 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1643 std::vector<uint8_t> ech_config;
1644 ASSERT_TRUE(MakeECHConfig(
David Benjaminc3b373b2021-06-06 13:04:26 -04001645 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHPublicKey,
David Benjaminf39c81d2021-05-03 18:39:46 -04001646 std::vector<uint16_t>{0x002 /* HKDF-SHA384 */, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001647 /*extensions=*/{}));
David Benjaminc3b373b2021-06-06 13:04:26 -04001648 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1649 ech_config.data(), ech_config.size(),
1650 kECHPrivateKey, sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001651
1652 // Unsupported KEMs are rejected.
1653 static const uint8_t kP256PublicKey[] = {
1654 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f,
1655 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e,
1656 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a,
1657 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3,
1658 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5,
1659 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1};
1660 static const uint8_t kP256PrivateKey[] = {
1661 0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59,
1662 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30,
1663 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a};
1664 ASSERT_TRUE(MakeECHConfig(
Steven Valdez94a63a52021-04-29 10:52:42 -04001665 &ech_config, 0x42, 0x0010 /* DHKEM(P-256, HKDF-SHA256) */, kP256PublicKey,
David Benjaminf39c81d2021-05-03 18:39:46 -04001666 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001667 /*extensions=*/{}));
David Benjaminc3b373b2021-06-06 13:04:26 -04001668 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1669 ech_config.data(), ech_config.size(),
1670 kP256PrivateKey, sizeof(kP256PrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001671
1672 // Unsupported extensions are rejected.
1673 static const uint8_t kExtensions[] = {0x00, 0x01, 0x00, 0x00};
1674 ASSERT_TRUE(MakeECHConfig(
David Benjaminc3b373b2021-06-06 13:04:26 -04001675 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHPublicKey,
David Benjaminf39c81d2021-05-03 18:39:46 -04001676 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001677 kExtensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001678 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1679 ech_config.data(), ech_config.size(),
1680 kECHPrivateKey, sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001681}
1682
David Benjaminc79ae7a2017-08-29 16:09:44 -04001683static void AppendSession(SSL_SESSION *session, void *arg) {
1684 std::vector<SSL_SESSION*> *out =
1685 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1686 out->push_back(session);
1687}
1688
1689// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1690// order.
1691static bool CacheEquals(SSL_CTX *ctx,
1692 const std::vector<SSL_SESSION*> &expected) {
1693 // Check the linked list.
1694 SSL_SESSION *ptr = ctx->session_cache_head;
1695 for (SSL_SESSION *session : expected) {
1696 if (ptr != session) {
1697 return false;
1698 }
1699 // TODO(davidben): This is an absurd way to denote the end of the list.
1700 if (ptr->next ==
1701 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1702 ptr = nullptr;
1703 } else {
1704 ptr = ptr->next;
1705 }
1706 }
1707 if (ptr != nullptr) {
1708 return false;
1709 }
1710
1711 // Check the hash table.
1712 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001713 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001714 expected_copy = expected;
1715
1716 std::sort(actual.begin(), actual.end());
1717 std::sort(expected_copy.begin(), expected_copy.end());
1718
1719 return actual == expected_copy;
1720}
1721
1722static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1723 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1724 if (!ssl_ctx) {
1725 return nullptr;
1726 }
1727 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1728 if (!ret) {
1729 return nullptr;
1730 }
1731
David Benjaminaaef8332018-06-29 16:45:49 -04001732 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1733 OPENSSL_memcpy(id, &number, sizeof(number));
1734 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1735 return nullptr;
1736 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001737 return ret;
1738}
1739
1740// Test that the internal session cache behaves as expected.
1741TEST(SSLTest, InternalSessionCache) {
1742 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1743 ASSERT_TRUE(ctx);
1744
1745 // Prepare 10 test sessions.
1746 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1747 for (int i = 0; i < 10; i++) {
1748 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1749 ASSERT_TRUE(session);
1750 sessions.push_back(std::move(session));
1751 }
1752
1753 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1754
1755 // Insert all the test sessions.
1756 for (const auto &session : sessions) {
1757 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1758 }
1759
1760 // Only the last five should be in the list.
1761 ASSERT_TRUE(CacheEquals(
1762 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1763 sessions[6].get(), sessions[5].get()}));
1764
1765 // Inserting an element already in the cache should fail and leave the cache
1766 // unchanged.
1767 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1768 ASSERT_TRUE(CacheEquals(
1769 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1770 sessions[6].get(), sessions[5].get()}));
1771
1772 // Although collisions should be impossible (256-bit session IDs), the cache
1773 // must handle them gracefully.
1774 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1775 ASSERT_TRUE(collision);
1776 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1777 ASSERT_TRUE(CacheEquals(
1778 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1779 sessions[6].get(), sessions[5].get()}));
1780
1781 // Removing sessions behaves correctly.
1782 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1783 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1784 sessions[8].get(), sessions[5].get()}));
1785
1786 // Removing sessions requires an exact match.
1787 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1788 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1789
1790 // The cache remains unchanged.
1791 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1792 sessions[8].get(), sessions[5].get()}));
1793}
1794
1795static uint16_t EpochFromSequence(uint64_t seq) {
1796 return static_cast<uint16_t>(seq >> 48);
1797}
1798
David Benjamin71dfad42017-07-16 17:27:39 -04001799static const uint8_t kTestName[] = {
1800 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1801 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1802 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1803 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1804 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1805 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1806};
1807
David Benjaminb79cc842016-12-07 15:57:14 -05001808static bool CompleteHandshakes(SSL *client, SSL *server) {
1809 // Drive both their handshakes to completion.
1810 for (;;) {
1811 int client_ret = SSL_do_handshake(client);
1812 int client_err = SSL_get_error(client, client_ret);
1813 if (client_err != SSL_ERROR_NONE &&
1814 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001815 client_err != SSL_ERROR_WANT_WRITE &&
1816 client_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001817 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001818 return false;
1819 }
1820
1821 int server_ret = SSL_do_handshake(server);
1822 int server_err = SSL_get_error(server, server_ret);
1823 if (server_err != SSL_ERROR_NONE &&
1824 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001825 server_err != SSL_ERROR_WANT_WRITE &&
1826 server_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001827 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001828 return false;
1829 }
1830
1831 if (client_ret == 1 && server_ret == 1) {
1832 break;
1833 }
1834 }
1835
1836 return true;
1837}
1838
Steven Valdez777a2392019-02-21 11:30:47 -05001839static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1840 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1841 // not pick them up until |SSL_read|.
1842 for (;;) {
1843 int server_ret = SSL_write(server, nullptr, 0);
1844 int server_err = SSL_get_error(server, server_ret);
1845 // The server may either succeed (|server_ret| is zero) or block on write
1846 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1847 if (server_ret > 0 ||
1848 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1849 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1850 server_err);
1851 return false;
1852 }
1853
1854 int client_ret = SSL_read(client, nullptr, 0);
1855 int client_err = SSL_get_error(client, client_ret);
1856 // The client must always block on read.
1857 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1858 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1859 client_err);
1860 return false;
1861 }
1862
1863 // The server flushed everything it had to write.
1864 if (server_ret == 0) {
1865 return true;
1866 }
1867 }
1868}
1869
David Benjamin9b2cdb72021-04-01 23:21:53 -04001870// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1871// are paired with each other. It does not run the handshake. The caller is
1872// expected to configure the objects and drive the handshake as needed.
1873static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1874 bssl::UniquePtr<SSL> *out_server,
1875 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1876 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1877 if (!client || !server) {
1878 return false;
1879 }
1880 SSL_set_connect_state(client.get());
1881 SSL_set_accept_state(server.get());
1882
1883 BIO *bio1, *bio2;
1884 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1885 return false;
1886 }
1887 // SSL_set_bio takes ownership.
1888 SSL_set_bio(client.get(), bio1, bio1);
1889 SSL_set_bio(server.get(), bio2, bio2);
1890
1891 *out_client = std::move(client);
1892 *out_server = std::move(server);
1893 return true;
1894}
1895
David Benjamina8614602017-09-06 15:40:19 -04001896struct ClientConfig {
1897 SSL_SESSION *session = nullptr;
1898 std::string servername;
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001899 bool early_data = false;
David Benjamina8614602017-09-06 15:40:19 -04001900};
1901
David Benjaminb79cc842016-12-07 15:57:14 -05001902static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1903 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001904 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001905 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001906 bool shed_handshake_config = true) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04001907 bssl::UniquePtr<SSL> client, server;
1908 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
David Benjaminde942382016-02-11 12:02:01 -05001909 return false;
1910 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001911 if (config.early_data) {
1912 SSL_set_early_data_enabled(client.get(), 1);
1913 }
David Benjamina8614602017-09-06 15:40:19 -04001914 if (config.session) {
1915 SSL_set_session(client.get(), config.session);
1916 }
1917 if (!config.servername.empty() &&
1918 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1919 return false;
1920 }
David Benjamina20e5352016-08-02 19:09:41 -04001921
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001922 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1923 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1924
David Benjamin9b2cdb72021-04-01 23:21:53 -04001925 if (!CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001926 return false;
David Benjaminde942382016-02-11 12:02:01 -05001927 }
1928
David Benjamin686bb192016-05-10 15:15:41 -04001929 *out_client = std::move(client);
1930 *out_server = std::move(server);
1931 return true;
1932}
1933
David Benjaminc11ea9422017-08-29 16:33:21 -04001934// SSLVersionTest executes its test cases under all available protocol versions.
1935// Test cases call |Connect| to create a connection using context objects with
1936// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001937class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1938 protected:
1939 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1940
1941 void SetUp() { ResetContexts(); }
1942
1943 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1944 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1945 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1946 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1947 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1948 return nullptr;
1949 }
1950 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001951 }
David Benjamin686bb192016-05-10 15:15:41 -04001952
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001953 void ResetContexts() {
1954 ASSERT_TRUE(cert_);
1955 ASSERT_TRUE(key_);
1956 client_ctx_ = CreateContext();
1957 ASSERT_TRUE(client_ctx_);
1958 server_ctx_ = CreateContext();
1959 ASSERT_TRUE(server_ctx_);
1960 // Set up a server cert. Client certs can be set up explicitly.
1961 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001962 }
David Benjamin686bb192016-05-10 15:15:41 -04001963
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001964 bool UseCertAndKey(SSL_CTX *ctx) const {
1965 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1966 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001967 }
David Benjamin686bb192016-05-10 15:15:41 -04001968
David Benjamina8614602017-09-06 15:40:19 -04001969 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001970 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04001971 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001972 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001973 }
1974
1975 uint16_t version() const { return GetParam().version; }
1976
1977 bool is_dtls() const {
1978 return GetParam().ssl_method == VersionParam::is_dtls;
1979 }
1980
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001981 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001982 bssl::UniquePtr<SSL> client_, server_;
1983 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1984 bssl::UniquePtr<X509> cert_;
1985 bssl::UniquePtr<EVP_PKEY> key_;
1986};
1987
David Benjaminbe7006a2019-04-09 18:05:02 -05001988INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
1989 testing::ValuesIn(kAllVersions),
1990 [](const testing::TestParamInfo<VersionParam> &i) {
1991 return i.param.name;
1992 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001993
1994TEST_P(SSLVersionTest, SequenceNumber) {
1995 ASSERT_TRUE(Connect());
1996
David Benjamin0fef3052016-11-18 15:11:10 +09001997 // Drain any post-handshake messages to ensure there are no unread records
1998 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05001999 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002000
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002001 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2002 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2003 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2004 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002005
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002006 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002007 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002008 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2009 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2010 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2011 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002012
2013 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002014 EXPECT_GT(client_write_seq, server_read_seq);
2015 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002016 } else {
2017 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002018 EXPECT_EQ(client_write_seq, server_read_seq);
2019 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002020 }
2021
2022 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002023 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002024 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2025 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002026
2027 // The client write and server read sequence numbers should have
2028 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002029 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2030 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002031}
2032
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002033TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002034 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002035 if (is_dtls()) {
2036 return;
David Benjamin686bb192016-05-10 15:15:41 -04002037 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002038 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002039
2040 // Shut down half the connection. SSL_shutdown will return 0 to signal only
2041 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002042 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002043
2044 // Reading from the server should consume the EOF.
2045 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002046 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2047 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002048
2049 // However, the server may continue to write data and then shut down the
2050 // connection.
2051 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002052 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2053 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2054 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002055
2056 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002057 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2058 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002059}
David Benjamin68f37b72016-11-18 15:14:42 +09002060
David Benjaminf0d8e222017-02-04 10:58:26 -05002061TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002062 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002063 bssl::UniquePtr<SSL_CTX> server_ctx =
2064 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002065 ASSERT_TRUE(client_ctx);
2066 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002067
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002068 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002069 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002070 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002071
2072 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002073 bssl::UniquePtr<SSL_SESSION> session1 =
2074 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002075 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002076
David Benjamina3a71e92018-06-29 13:24:45 -04002077 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002078
Steven Valdez87eab492016-06-27 16:34:59 -04002079 uint8_t *s0_bytes, *s1_bytes;
2080 size_t s0_len, s1_len;
2081
David Benjaminf0d8e222017-02-04 10:58:26 -05002082 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002083 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002084
David Benjaminf0d8e222017-02-04 10:58:26 -05002085 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002086 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002087
David Benjamin7d7554b2017-02-04 11:48:59 -05002088 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002089}
David Benjamin686bb192016-05-10 15:15:41 -04002090
David Benjaminf0d8e222017-02-04 10:58:26 -05002091static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002092 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002093 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2094 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002095
2096 // The wrapper BIOs are always equal when fds are equal, even if set
2097 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002098 if (rfd == wfd) {
2099 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002100 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002101}
2102
David Benjaminf0d8e222017-02-04 10:58:26 -05002103TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002104 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002105 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002106
2107 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002108 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002109 ASSERT_TRUE(ssl);
2110 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2111 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2112 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002113
2114 // Test setting the same FD.
2115 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002116 ASSERT_TRUE(ssl);
2117 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2118 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002119
2120 // Test setting the same FD one side at a time.
2121 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002122 ASSERT_TRUE(ssl);
2123 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2124 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2125 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002126
2127 // Test setting the same FD in the other order.
2128 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002129 ASSERT_TRUE(ssl);
2130 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2131 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2132 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002133
David Benjamin5c0fb882016-06-14 14:03:51 -04002134 // Test changing the read FD partway through.
2135 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002136 ASSERT_TRUE(ssl);
2137 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2138 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2139 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002140
2141 // Test changing the write FD partway through.
2142 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002143 ASSERT_TRUE(ssl);
2144 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2145 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2146 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002147
2148 // Test a no-op change to the read FD partway through.
2149 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002150 ASSERT_TRUE(ssl);
2151 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2152 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2153 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002154
2155 // Test a no-op change to the write FD partway through.
2156 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002157 ASSERT_TRUE(ssl);
2158 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2159 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2160 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002161
2162 // ASan builds will implicitly test that the internal |BIO| reference-counting
2163 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002164}
2165
David Benjaminf0d8e222017-02-04 10:58:26 -05002166TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002167 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002168 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002169
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002170 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2171 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002172 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002173 ASSERT_TRUE(ssl);
2174 ASSERT_TRUE(bio1);
2175 ASSERT_TRUE(bio2);
2176 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002177
2178 // SSL_set_bio takes one reference when the parameters are the same.
2179 BIO_up_ref(bio1.get());
2180 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2181
2182 // Repeating the call does nothing.
2183 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2184
2185 // It takes one reference each when the parameters are different.
2186 BIO_up_ref(bio2.get());
2187 BIO_up_ref(bio3.get());
2188 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2189
2190 // Repeating the call does nothing.
2191 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2192
2193 // It takes one reference when changing only wbio.
2194 BIO_up_ref(bio1.get());
2195 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2196
2197 // It takes one reference when changing only rbio and the two are different.
2198 BIO_up_ref(bio3.get());
2199 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2200
2201 // If setting wbio to rbio, it takes no additional references.
2202 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2203
2204 // From there, wbio may be switched to something else.
2205 BIO_up_ref(bio1.get());
2206 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2207
2208 // If setting rbio to wbio, it takes no additional references.
2209 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2210
2211 // From there, rbio may be switched to something else, but, for historical
2212 // reasons, it takes a reference to both parameters.
2213 BIO_up_ref(bio1.get());
2214 BIO_up_ref(bio2.get());
2215 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2216
2217 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2218 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002219}
2220
David Benjamin25490f22016-07-14 00:22:54 -04002221static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2222
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002223TEST_P(SSLVersionTest, GetPeerCertificate) {
2224 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002225
David Benjamin0fef3052016-11-18 15:11:10 +09002226 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002227 SSL_CTX_set_verify(client_ctx_.get(),
2228 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2229 nullptr);
2230 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2231 SSL_CTX_set_verify(server_ctx_.get(),
2232 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2233 nullptr);
2234 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002235
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002236 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002237
David Benjamin0fef3052016-11-18 15:11:10 +09002238 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002239 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2240 ASSERT_TRUE(peer);
2241 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002242
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002243 peer.reset(SSL_get_peer_certificate(client_.get()));
2244 ASSERT_TRUE(peer);
2245 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002246
David Benjamine664a532017-07-20 20:19:36 -04002247 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002248 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002249 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2250 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2251 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002252
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002253 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2254 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2255 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002256}
2257
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002258TEST_P(SSLVersionTest, NoPeerCertificate) {
2259 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2260 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2261 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002262
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002263 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002264
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002265 // Server should not see a peer certificate.
2266 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2267 ASSERT_FALSE(peer);
2268 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002269}
2270
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002271TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002272 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002273 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2274 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002275 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002276
2277 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2278 SHA256(cert_der, cert_der_len, cert_sha256);
2279
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002280 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2281
David Benjamin0fef3052016-11-18 15:11:10 +09002282 // Configure both client and server to accept any certificate, but the
2283 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002284 SSL_CTX_set_verify(client_ctx_.get(),
2285 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2286 nullptr);
2287 SSL_CTX_set_verify(server_ctx_.get(),
2288 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2289 nullptr);
2290 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2291 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2292 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002293
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002294 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002295
David Benjamin0fef3052016-11-18 15:11:10 +09002296 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002297 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2298 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002299
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002300 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002301 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002302
David Benjamin02de7bd2018-05-08 18:13:54 -04002303 const uint8_t *peer_sha256;
2304 size_t peer_sha256_len;
2305 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2306 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002307}
2308
David Benjamin737d2df2017-09-25 15:05:19 -04002309// Tests that our ClientHellos do not change unexpectedly. These are purely
2310// change detection tests. If they fail as part of an intentional ClientHello
2311// change, update the test vector.
2312TEST(SSLTest, ClientHello) {
2313 struct {
2314 uint16_t max_version;
2315 std::vector<uint8_t> expected;
2316 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002317 {TLS1_VERSION,
2318 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2322 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002323 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2324 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2325 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002326 {TLS1_1_VERSION,
2327 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2329 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2331 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002332 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2333 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2334 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002335 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002336 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002340 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002341 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002342 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2343 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2344 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2345 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2346 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2347 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002348 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2349 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002350 };
David Benjamin737d2df2017-09-25 15:05:19 -04002351
2352 for (const auto &t : kTests) {
2353 SCOPED_TRACE(t.max_version);
2354
2355 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2356 ASSERT_TRUE(ctx);
2357 // Our default cipher list varies by CPU capabilities, so manually place the
2358 // ChaCha20 ciphers in front.
2359 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002360 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2361 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2362
2363 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2364 ASSERT_TRUE(ssl);
2365 std::vector<uint8_t> client_hello;
2366 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2367
2368 // Zero the client_random.
2369 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2370 1 + 3 + // handshake message header
2371 2; // client_version
2372 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2373 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2374
2375 if (client_hello != t.expected) {
2376 ADD_FAILURE() << "ClientHellos did not match.";
2377 // Print the value manually so it is easier to update the test vector.
2378 for (size_t i = 0; i < client_hello.size(); i += 12) {
2379 printf(" %c", i == 0 ? '{' : ' ');
2380 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2381 if (j > i) {
2382 printf(" ");
2383 }
2384 printf("0x%02x", client_hello[j]);
2385 if (j < client_hello.size() - 1) {
2386 printf(",");
2387 }
2388 }
2389 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002390 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002391 }
2392 printf("\n");
2393 }
2394 }
David Benjaminafc64de2016-07-19 17:12:41 +02002395 }
David Benjaminafc64de2016-07-19 17:12:41 +02002396}
2397
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002398static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002399
2400static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2401 // Save the most recent session.
2402 g_last_session.reset(session);
2403 return 1;
2404}
2405
David Benjamina8614602017-09-06 15:40:19 -04002406static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2407 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2408 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002409 g_last_session = nullptr;
2410 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2411
2412 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002413 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002414 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002415 config) ||
2416 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002417 fprintf(stderr, "Failed to connect client and server.\n");
2418 return nullptr;
2419 }
2420
David Benjamina20e5352016-08-02 19:09:41 -04002421 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2422
2423 if (!g_last_session) {
2424 fprintf(stderr, "Client did not receive a session.\n");
2425 return nullptr;
2426 }
2427 return std::move(g_last_session);
2428}
2429
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002430static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2431 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002432 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002433 ClientConfig config;
2434 config.session = session;
2435 EXPECT_TRUE(
2436 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002437
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002438 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002439
2440 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002441 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002442}
2443
David Benjamin3c51d9b2016-11-01 17:50:42 -04002444static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2445 SSL_CTX *server_ctx,
2446 SSL_SESSION *session) {
2447 g_last_session = nullptr;
2448 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2449
2450 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002451 ClientConfig config;
2452 config.session = session;
2453 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002454 config) ||
2455 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002456 fprintf(stderr, "Failed to connect client and server.\n");
2457 return nullptr;
2458 }
2459
2460 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2461 fprintf(stderr, "Client and server were inconsistent.\n");
2462 return nullptr;
2463 }
2464
2465 if (!SSL_session_reused(client.get())) {
2466 fprintf(stderr, "Session was not reused.\n");
2467 return nullptr;
2468 }
2469
David Benjamin3c51d9b2016-11-01 17:50:42 -04002470 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2471
2472 if (!g_last_session) {
2473 fprintf(stderr, "Client did not receive a renewed session.\n");
2474 return nullptr;
2475 }
2476 return std::move(g_last_session);
2477}
2478
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002479static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002480 bool changed) {
2481 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002482 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002483 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2484 if (changed) {
2485 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2486 } else {
2487 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002488 }
2489 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002490}
2491
David Benjamina933c382016-10-28 00:10:03 -04002492static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2493 static const uint8_t kContext[] = {3};
2494
2495 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2496 return SSL_TLSEXT_ERR_ALERT_FATAL;
2497 }
2498
2499 return SSL_TLSEXT_ERR_OK;
2500}
2501
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002502TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002503 static const uint8_t kContext1[] = {1};
2504 static const uint8_t kContext2[] = {2};
2505
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002506 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2507 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002508
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002509 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2510 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002511
David Benjamin0fef3052016-11-18 15:11:10 +09002512 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2514 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002515
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002516 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2517 session.get(),
2518 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002519
David Benjamin0fef3052016-11-18 15:11:10 +09002520 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002521 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2522 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002523
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002524 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2525 session.get(),
2526 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002527
David Benjamin0fef3052016-11-18 15:11:10 +09002528 // Change the session ID context back and install an SNI callback to switch
2529 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002530 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2531 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002532
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002533 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002534 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002535
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002536 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2537 session.get(),
2538 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002539
David Benjamin0fef3052016-11-18 15:11:10 +09002540 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002541 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002542 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002543 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002544 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2545 static const uint8_t kContext[] = {3};
2546
2547 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2548 sizeof(kContext))) {
2549 return ssl_select_cert_error;
2550 }
2551
2552 return ssl_select_cert_success;
2553 });
David Benjamina933c382016-10-28 00:10:03 -04002554
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002555 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2556 session.get(),
2557 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002558}
2559
David Benjamin721e8b72016-08-03 13:13:17 -04002560static timeval g_current_time;
2561
2562static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2563 *out_clock = g_current_time;
2564}
2565
David Benjamin17b30832017-01-28 14:00:32 -05002566static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2567 out_clock->tv_sec = 1000;
2568 out_clock->tv_usec = 0;
2569}
2570
David Benjamin3c51d9b2016-11-01 17:50:42 -04002571static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2572 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2573 int encrypt) {
2574 static const uint8_t kZeros[16] = {0};
2575
2576 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002577 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002578 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002579 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002580 return 0;
2581 }
2582
2583 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2584 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2585 return -1;
2586 }
2587
2588 // Returning two from the callback in decrypt mode renews the
2589 // session in TLS 1.2 and below.
2590 return encrypt ? 1 : 2;
2591}
2592
David Benjamin123db572016-11-03 16:59:25 -04002593static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002594 const uint8_t *ticket;
2595 size_t ticket_len;
2596 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2597 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002598 return false;
2599 }
2600
David Benjaminaaef8332018-06-29 16:45:49 -04002601 const uint8_t *ciphertext = ticket + 16 + 16;
2602 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002603 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2604
David Benjamin9b63f292016-11-15 00:44:05 -05002605#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2606 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002607 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002608#else
2609 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002610 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002611 bssl::ScopedEVP_CIPHER_CTX ctx;
2612 int len1, len2;
2613 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2614 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2615 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2616 return false;
2617 }
2618
2619 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002620#endif
David Benjamin123db572016-11-03 16:59:25 -04002621
Adam Langley46db7af2017-02-01 15:49:37 -08002622 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2623 if (!ssl_ctx) {
2624 return false;
2625 }
David Benjamin123db572016-11-03 16:59:25 -04002626 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002627 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002628 if (!server_session) {
2629 return false;
2630 }
2631
David Benjaminaaef8332018-06-29 16:45:49 -04002632 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002633 return true;
2634}
2635
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002636TEST_P(SSLVersionTest, SessionTimeout) {
2637 for (bool server_test : {false, true}) {
2638 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002639
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002640 ResetContexts();
2641 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2642 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2643
David Benjamin17b30832017-01-28 14:00:32 -05002644 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002645 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002646
David Benjamin17b30832017-01-28 14:00:32 -05002647 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2648 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002649 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002650 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2651 : SSL_DEFAULT_SESSION_TIMEOUT;
2652
David Benjamin17b30832017-01-28 14:00:32 -05002653 // Both client and server must enforce session timeouts. We configure the
2654 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002655 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002656 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2657 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002658 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002659 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2660 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002661 }
2662
2663 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002664 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002665
2666 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002667 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2668 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002669
2670 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002671 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002672
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002673 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2674 session.get(),
2675 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002676
2677 // Advance the clock one more second.
2678 g_current_time.tv_sec++;
2679
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002680 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2681 session.get(),
2682 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002683
2684 // Rewind the clock to before the session was minted.
2685 g_current_time.tv_sec = kStartTime - 1;
2686
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002687 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2688 session.get(),
2689 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002690
David Benjamin0fef3052016-11-18 15:11:10 +09002691 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002692 time_t new_start_time = kStartTime + timeout - 10;
2693 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002694 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2695 client_ctx_.get(), server_ctx_.get(), session.get());
2696 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002697
2698 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002700
2701 // Check the sessions have timestamps measured from issuance.
2702 long session_time = 0;
2703 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002704 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002705 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002706 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002707 }
David Benjamin721e8b72016-08-03 13:13:17 -04002708
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002709 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002710
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002711 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002712 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2713 // lifetime TLS 1.3.
2714 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002715 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2716 new_session.get(),
2717 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002718
David Benjamin17b30832017-01-28 14:00:32 -05002719 // The new session expires after the new timeout.
2720 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2722 new_session.get(),
2723 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002724
2725 // Renew the session until it begins just past the auth timeout.
2726 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2727 while (new_start_time < auth_end_time - 1000) {
2728 // Get as close as possible to target start time.
2729 new_start_time =
2730 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2731 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002732 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002733 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002734 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002735 }
2736
2737 // Now the session's lifetime is bound by the auth timeout.
2738 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002739 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2740 new_session.get(),
2741 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002742
2743 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2745 new_session.get(),
2746 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002747 } else {
2748 // The new session is usable just before the old expiration.
2749 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002750 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2751 new_session.get(),
2752 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002753
2754 // Renewal does not extend the lifetime, so it is not usable beyond the
2755 // old expiration.
2756 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002757 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2758 new_session.get(),
2759 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002760 }
David Benjamin721e8b72016-08-03 13:13:17 -04002761 }
David Benjamin721e8b72016-08-03 13:13:17 -04002762}
2763
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002764TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002765 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2766 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002767 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002768 kTicketKeyLen));
2769 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2770}
2771
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002772TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002773 static const time_t kStartTime = 1001;
2774 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002775
David Benjaminc11ea9422017-08-29 16:33:21 -04002776 // We use session reuse as a proxy for ticket decryption success, hence
2777 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002778 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2779 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002780 std::numeric_limits<uint32_t>::max());
2781
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002782 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2783 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002784
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002785 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2786 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002787
David Benjamin1f0d54b2018-08-09 16:19:13 -05002788 // Initialize ticket_key with the current key and check that it was
2789 // initialized to something, not all zeros.
2790 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002791 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2792 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002793
David Benjaminc11ea9422017-08-29 16:33:21 -04002794 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002795 bssl::UniquePtr<SSL> client, server;
2796 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002797 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002798 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002800 session.get(), true /* reused */));
2801
David Benjaminc11ea9422017-08-29 16:33:21 -04002802 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002803 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002805 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002806 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002807 false /* NOT changed */));
2808
David Benjaminc11ea9422017-08-29 16:33:21 -04002809 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002810 g_current_time.tv_sec += 1;
2811 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002812 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2813 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2814 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002815
David Benjaminc11ea9422017-08-29 16:33:21 -04002816 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002817 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002818 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002819 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002820 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002821 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002822 false /* NOT changed */));
2823
David Benjaminc11ea9422017-08-29 16:33:21 -04002824 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002825 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002826 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002827 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002828 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2829 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002830
David Benjaminc11ea9422017-08-29 16:33:21 -04002831 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002833 new_session.get(), true /* reused */));
2834}
2835
David Benjamin0fc37ef2016-08-17 15:29:46 -04002836static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002837 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002838 SSL_set_SSL_CTX(ssl, ctx);
2839 return SSL_TLSEXT_ERR_OK;
2840}
2841
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002842TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002843 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002844 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002845 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002846 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002847
David Benjamin0fef3052016-11-18 15:11:10 +09002848 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2849 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002850
David Benjamin83a32122017-02-14 18:34:54 -05002851 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2852 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2853
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002854 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2855 ASSERT_TRUE(server_ctx2);
2856 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2857 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2858 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2859 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2860 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2861 sizeof(kOCSPResponse)));
2862 // Historically signing preferences would be lost in some cases with the
2863 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2864 // this doesn't happen when |version| is TLS 1.2, configure the private
2865 // key to only sign SHA-256.
2866 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2867 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002868
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002869 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2870 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002871
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002872 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2873 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002874
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002875 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002876
David Benjamin0fef3052016-11-18 15:11:10 +09002877 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002878 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2879 ASSERT_TRUE(peer);
2880 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002881
David Benjamin83a32122017-02-14 18:34:54 -05002882 // The client should have received |server_ctx2|'s SCT list.
2883 const uint8_t *data;
2884 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002885 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2886 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002887
2888 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002889 SSL_get0_ocsp_response(client_.get(), &data, &len);
2890 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002891}
2892
David Benjaminf0d8e222017-02-04 10:58:26 -05002893// Test that the early callback can swap the maximum version.
2894TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04002895 bssl::UniquePtr<SSL_CTX> server_ctx =
2896 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002897 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002898 ASSERT_TRUE(server_ctx);
2899 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05002900 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2901 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002902
David Benjaminf0d8e222017-02-04 10:58:26 -05002903 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002904 server_ctx.get(),
2905 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002906 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002907 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002908 }
2909
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002910 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002911 });
David Benjamin99620572016-08-30 00:35:36 -04002912
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002913 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002914 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002915 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002916 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002917}
2918
David Benjaminf0d8e222017-02-04 10:58:26 -05002919TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002920 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002921 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002922
David Benjaminf0d8e222017-02-04 10:58:26 -05002923 // Set valid TLS versions.
2924 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2925 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2926 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2927 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002928
David Benjaminf0d8e222017-02-04 10:58:26 -05002929 // Invalid TLS versions are rejected.
2930 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2931 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2932 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2933 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2934 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2935 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002936
David Benjaminf0d8e222017-02-04 10:58:26 -05002937 // Zero is the default version.
2938 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08002939 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002940 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002941 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05002942
David Benjamin9bb15f52018-06-26 00:07:40 -04002943 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002944 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002945 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04002946
David Benjamin9bb15f52018-06-26 00:07:40 -04002947 // SSL 3.0 is not available.
2948 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2949
David Benjamin2dc02042016-09-19 19:57:37 -04002950 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002951 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002952
David Benjaminf0d8e222017-02-04 10:58:26 -05002953 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2954 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2955 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2956 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002957
David Benjaminf0d8e222017-02-04 10:58:26 -05002958 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2959 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2960 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2961 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2962 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2963 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2964 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2965 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002966
David Benjaminf0d8e222017-02-04 10:58:26 -05002967 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002968 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002969 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002970 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04002971}
2972
David Benjamin458334a2016-12-15 13:53:25 -05002973static const char *GetVersionName(uint16_t version) {
2974 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002975 case TLS1_VERSION:
2976 return "TLSv1";
2977 case TLS1_1_VERSION:
2978 return "TLSv1.1";
2979 case TLS1_2_VERSION:
2980 return "TLSv1.2";
2981 case TLS1_3_VERSION:
2982 return "TLSv1.3";
2983 case DTLS1_VERSION:
2984 return "DTLSv1";
2985 case DTLS1_2_VERSION:
2986 return "DTLSv1.2";
2987 default:
2988 return "???";
2989 }
2990}
2991
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002992TEST_P(SSLVersionTest, Version) {
2993 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002994
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002995 EXPECT_EQ(SSL_version(client_.get()), version());
2996 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002997
David Benjamin458334a2016-12-15 13:53:25 -05002998 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002999 const char *version_name = GetVersionName(version());
3000 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3001 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003002
3003 // Test SSL_SESSION reports the same name.
3004 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003005 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003006 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003007 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3008 EXPECT_EQ(strcmp(version_name, client_name), 0);
3009 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003010}
3011
David Benjamin9ef31f02016-10-31 18:01:13 -04003012// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3013// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003014TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003015 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3016
David Benjamin9ef31f02016-10-31 18:01:13 -04003017 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003018 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3019 sizeof(kALPNProtos)),
3020 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003021
3022 // The ALPN callback does not fail the handshake on error, so have the
3023 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003024 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003025 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003026 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003027 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3028 unsigned in_len, void *arg) -> int {
3029 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3030 if (SSL_get_pending_cipher(ssl) != nullptr &&
3031 SSL_version(ssl) == state->first) {
3032 state->second = true;
3033 }
3034 return SSL_TLSEXT_ERR_NOACK;
3035 },
3036 &callback_state);
3037
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003038 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003039
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003040 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003041}
3042
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003043TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003044 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3045 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003046 if (version() == TLS1_3_VERSION) {
3047 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003048 }
3049
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003050 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003051 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003052
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003053 EXPECT_FALSE(SSL_session_reused(client_.get()));
3054 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003055
3056 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003057 ASSERT_TRUE(SSL_clear(client_.get()));
3058 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003059
3060 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003061 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003062
3063 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003064 EXPECT_TRUE(SSL_session_reused(client_.get()));
3065 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003066}
3067
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003068TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3069 shed_handshake_config_ = false;
3070 ASSERT_TRUE(Connect());
3071 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3072
3073 // Reset everything.
3074 ASSERT_TRUE(SSL_clear(client_.get()));
3075 ASSERT_TRUE(SSL_clear(server_.get()));
3076
3077 // Now enable shedding, and connect a second time.
3078 shed_handshake_config_ = true;
3079 ASSERT_TRUE(Connect());
3080 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3081
3082 // |SSL_clear| should now fail.
3083 ASSERT_FALSE(SSL_clear(client_.get()));
3084 ASSERT_FALSE(SSL_clear(server_.get()));
3085}
3086
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003087static bool ChainsEqual(STACK_OF(X509) * chain,
3088 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003089 if (sk_X509_num(chain) != expected.size()) {
3090 return false;
3091 }
3092
3093 for (size_t i = 0; i < expected.size(); i++) {
3094 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3095 return false;
3096 }
3097 }
3098
3099 return true;
3100}
3101
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003102TEST_P(SSLVersionTest, AutoChain) {
3103 cert_ = GetChainTestCertificate();
3104 ASSERT_TRUE(cert_);
3105 key_ = GetChainTestKey();
3106 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003107 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003108 ASSERT_TRUE(intermediate);
3109
3110 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3111 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003112
3113 // Configure both client and server to accept any certificate. Add
3114 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003115 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3116 intermediate.get()));
3117 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3118 intermediate.get()));
3119 SSL_CTX_set_verify(client_ctx_.get(),
3120 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3121 nullptr);
3122 SSL_CTX_set_verify(server_ctx_.get(),
3123 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3124 nullptr);
3125 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3126 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003127
3128 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003129 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003130
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003131 EXPECT_TRUE(
3132 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3133 EXPECT_TRUE(
3134 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003135
3136 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003137 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3138 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3139 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003140
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003141 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3142 {cert_.get(), intermediate.get()}));
3143 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3144 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003145
3146 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003147 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3148 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3149 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003150
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003151 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3152 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003153
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003154 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3155 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003156}
3157
David Benjamin48063c22017-01-01 23:56:36 -05003158static bool ExpectBadWriteRetry() {
3159 int err = ERR_get_error();
3160 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3161 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3162 char buf[ERR_ERROR_STRING_BUF_LEN];
3163 ERR_error_string_n(err, buf, sizeof(buf));
3164 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3165 return false;
3166 }
3167
3168 if (ERR_peek_error() != 0) {
3169 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3170 return false;
3171 }
3172
3173 return true;
3174}
3175
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003176TEST_P(SSLVersionTest, SSLWriteRetry) {
3177 if (is_dtls()) {
3178 return;
David Benjamin48063c22017-01-01 23:56:36 -05003179 }
3180
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003181 for (bool enable_partial_write : {false, true}) {
3182 SCOPED_TRACE(enable_partial_write);
3183
David Benjamin48063c22017-01-01 23:56:36 -05003184 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003185 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3186
3187 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003188
3189 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003190 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003191 }
3192
3193 // Write without reading until the buffer is full and we have an unfinished
3194 // write. Keep a count so we may reread it again later. "hello!" will be
3195 // written in two chunks, "hello" and "!".
3196 char data[] = "hello!";
3197 static const int kChunkLen = 5; // The length of "hello".
3198 unsigned count = 0;
3199 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003200 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003201 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003202 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3203 break;
David Benjamin48063c22017-01-01 23:56:36 -05003204 }
3205
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003206 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003207
3208 count++;
3209 }
3210
3211 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003212 ASSERT_EQ(
3213 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3214 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003215
3216 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003217 ASSERT_EQ(SSL_get_error(client_.get(),
3218 SSL_write(client_.get(), data, kChunkLen - 1)),
3219 SSL_ERROR_SSL);
3220 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003221
3222 // Retrying with a different buffer pointer is not legal.
3223 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003224 ASSERT_EQ(SSL_get_error(client_.get(),
3225 SSL_write(client_.get(), data2, kChunkLen)),
3226 SSL_ERROR_SSL);
3227 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003228
3229 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003230 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3231 ASSERT_EQ(SSL_get_error(client_.get(),
3232 SSL_write(client_.get(), data2, kChunkLen)),
3233 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003234
3235 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003236 ASSERT_EQ(SSL_get_error(client_.get(),
3237 SSL_write(client_.get(), data2, kChunkLen - 1)),
3238 SSL_ERROR_SSL);
3239 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003240
3241 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003242 ASSERT_EQ(SSL_get_error(client_.get(),
3243 SSL_write(client_.get(), data, kChunkLen + 1)),
3244 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003245
3246 // Drain the buffer.
3247 char buf[20];
3248 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003249 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3250 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003251 }
3252
3253 // Now that there is space, a retry with a larger buffer should flush the
3254 // pending record, skip over that many bytes of input (on assumption they
3255 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3256 // is set, this will complete in two steps.
3257 char data3[] = "_____!";
3258 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003259 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3260 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3261 } else {
3262 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003263 }
3264
3265 // Check the last write was correct. The data will be spread over two
3266 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003267 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3268 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3269 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3270 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003271 }
David Benjamin48063c22017-01-01 23:56:36 -05003272}
3273
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003274TEST_P(SSLVersionTest, RecordCallback) {
3275 for (bool test_server : {true, false}) {
3276 SCOPED_TRACE(test_server);
3277 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003278
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003279 bool read_seen = false;
3280 bool write_seen = false;
3281 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3282 size_t len, SSL *ssl) {
3283 if (cb_type != SSL3_RT_HEADER) {
3284 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003285 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003286
3287 // The callback does not report a version for records.
3288 EXPECT_EQ(0, cb_version);
3289
3290 if (is_write) {
3291 write_seen = true;
3292 } else {
3293 read_seen = true;
3294 }
3295
3296 // Sanity-check that the record header is plausible.
3297 CBS cbs;
3298 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3299 uint8_t type;
3300 uint16_t record_version, length;
3301 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3302 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003303 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003304 if (is_dtls()) {
3305 uint16_t epoch;
3306 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3307 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3308 ASSERT_TRUE(CBS_skip(&cbs, 6));
3309 }
3310 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3311 EXPECT_EQ(0u, CBS_len(&cbs));
3312 };
3313 using CallbackType = decltype(cb);
3314 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3315 SSL_CTX_set_msg_callback(
3316 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3317 size_t len, SSL *ssl, void *arg) {
3318 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3319 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3320 });
3321 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3322
3323 ASSERT_TRUE(Connect());
3324
3325 EXPECT_TRUE(read_seen);
3326 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003327 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003328}
3329
David Benjamina8614602017-09-06 15:40:19 -04003330TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003331 ClientConfig config;
3332 config.servername = "host1";
3333
3334 SSL_CTX_set_tlsext_servername_callback(
3335 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3336 // During the handshake, |SSL_get_servername| must match |config|.
3337 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3338 EXPECT_STREQ(config_p->servername.c_str(),
3339 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3340 return SSL_TLSEXT_ERR_OK;
3341 });
3342 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3343
3344 ASSERT_TRUE(Connect(config));
3345 // After the handshake, it must also be available.
3346 EXPECT_STREQ(config.servername.c_str(),
3347 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3348
3349 // Establish a session under host1.
3350 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3351 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3352 bssl::UniquePtr<SSL_SESSION> session =
3353 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3354
3355 // If the client resumes a session with a different name, |SSL_get_servername|
3356 // must return the new name.
3357 ASSERT_TRUE(session);
3358 config.session = session.get();
3359 config.servername = "host2";
3360 ASSERT_TRUE(Connect(config));
3361 EXPECT_STREQ(config.servername.c_str(),
3362 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3363}
3364
David Benjamin3d8f0802017-09-06 16:12:52 -04003365// Test that session cache mode bits are honored in the client session callback.
3366TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3367 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3368 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3369
3370 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3371 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3372
3373 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3374 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3375}
3376
Steven Valdez777a2392019-02-21 11:30:47 -05003377// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3378// NewSessionTickets are written post-handshake. Servers that block
3379// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3380// the buffer. Test that we do not do this.
3381TEST_P(SSLVersionTest, SmallBuffer) {
3382 // DTLS is a datagram protocol and requires packet-sized buffers.
3383 if (is_dtls()) {
3384 return;
3385 }
3386
3387 // Test both flushing NewSessionTickets with a zero-sized write and
3388 // non-zero-sized write.
3389 for (bool use_zero_write : {false, true}) {
3390 SCOPED_TRACE(use_zero_write);
3391
3392 g_last_session = nullptr;
3393 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3394 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3395
3396 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3397 server(SSL_new(server_ctx_.get()));
3398 ASSERT_TRUE(client);
3399 ASSERT_TRUE(server);
3400 SSL_set_connect_state(client.get());
3401 SSL_set_accept_state(server.get());
3402
3403 // Use a tiny buffer.
3404 BIO *bio1, *bio2;
3405 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3406
3407 // SSL_set_bio takes ownership.
3408 SSL_set_bio(client.get(), bio1, bio1);
3409 SSL_set_bio(server.get(), bio2, bio2);
3410
3411 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3412 if (version() >= TLS1_3_VERSION) {
3413 // The post-handshake ticket should not have been processed yet.
3414 EXPECT_FALSE(g_last_session);
3415 }
3416
3417 if (use_zero_write) {
3418 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3419 EXPECT_TRUE(g_last_session);
3420 }
3421
3422 // Send some data from server to client. If |use_zero_write| is false, this
3423 // will also flush the NewSessionTickets.
3424 static const char kMessage[] = "hello world";
3425 char buf[sizeof(kMessage)];
3426 for (;;) {
3427 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3428 int server_err = SSL_get_error(server.get(), server_ret);
3429 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3430 int client_err = SSL_get_error(client.get(), client_ret);
3431
3432 // The server will write a single record, so every iteration should see
3433 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3434 // iteration, where both will complete.
3435 if (server_ret > 0) {
3436 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3437 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3438 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3439 break;
3440 }
3441
3442 ASSERT_EQ(server_ret, -1);
3443 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3444 ASSERT_EQ(client_ret, -1);
3445 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3446 }
3447
3448 // The NewSessionTickets should have been flushed and processed.
3449 EXPECT_TRUE(g_last_session);
3450 }
3451}
3452
Adam Langleye1e78132017-01-31 15:24:31 -08003453TEST(SSLTest, AddChainCertHack) {
3454 // Ensure that we don't accidently break the hack that we have in place to
3455 // keep curl and serf happy when they use an |X509| even after transfering
3456 // ownership.
3457
3458 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3459 ASSERT_TRUE(ctx);
3460 X509 *cert = GetTestCertificate().release();
3461 ASSERT_TRUE(cert);
3462 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3463
3464 // This should not trigger a use-after-free.
3465 X509_cmp(cert, cert);
3466}
3467
David Benjaminb2ff2622017-02-03 17:06:18 -05003468TEST(SSLTest, GetCertificate) {
3469 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3470 ASSERT_TRUE(ctx);
3471 bssl::UniquePtr<X509> cert = GetTestCertificate();
3472 ASSERT_TRUE(cert);
3473 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3474 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3475 ASSERT_TRUE(ssl);
3476
3477 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3478 ASSERT_TRUE(cert2);
3479 X509 *cert3 = SSL_get_certificate(ssl.get());
3480 ASSERT_TRUE(cert3);
3481
3482 // The old and new certificates must be identical.
3483 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3484 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3485
3486 uint8_t *der = nullptr;
3487 long der_len = i2d_X509(cert.get(), &der);
3488 ASSERT_LT(0, der_len);
3489 bssl::UniquePtr<uint8_t> free_der(der);
3490
3491 uint8_t *der2 = nullptr;
3492 long der2_len = i2d_X509(cert2, &der2);
3493 ASSERT_LT(0, der2_len);
3494 bssl::UniquePtr<uint8_t> free_der2(der2);
3495
3496 uint8_t *der3 = nullptr;
3497 long der3_len = i2d_X509(cert3, &der3);
3498 ASSERT_LT(0, der3_len);
3499 bssl::UniquePtr<uint8_t> free_der3(der3);
3500
3501 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003502 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3503 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003504}
3505
Adam Langleyd04ca952017-02-28 11:26:51 -08003506TEST(SSLTest, SetChainAndKeyMismatch) {
3507 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3508 ASSERT_TRUE(ctx);
3509
3510 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3511 ASSERT_TRUE(key);
3512 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3513 ASSERT_TRUE(leaf);
3514 std::vector<CRYPTO_BUFFER*> chain = {
3515 leaf.get(),
3516 };
3517
3518 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3519 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3520 key.get(), nullptr));
3521 ERR_clear_error();
3522}
3523
3524TEST(SSLTest, SetChainAndKey) {
3525 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3526 ASSERT_TRUE(client_ctx);
3527 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3528 ASSERT_TRUE(server_ctx);
3529
Adam Langley964256d2020-03-19 11:57:12 -07003530 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
3531
Adam Langleyd04ca952017-02-28 11:26:51 -08003532 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3533 ASSERT_TRUE(key);
3534 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3535 ASSERT_TRUE(leaf);
3536 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3537 GetChainTestIntermediateBuffer();
3538 ASSERT_TRUE(intermediate);
3539 std::vector<CRYPTO_BUFFER*> chain = {
3540 leaf.get(), intermediate.get(),
3541 };
3542 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3543 chain.size(), key.get(), nullptr));
3544
Adam Langley964256d2020-03-19 11:57:12 -07003545 ASSERT_EQ(chain.size(),
3546 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
3547
David Benjamin3a1dd462017-07-11 16:13:10 -04003548 SSL_CTX_set_custom_verify(
3549 client_ctx.get(), SSL_VERIFY_PEER,
3550 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3551 return ssl_verify_ok;
3552 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003553
3554 bssl::UniquePtr<SSL> client, server;
3555 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003556 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003557}
3558
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003559TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3560 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3561 ASSERT_TRUE(client_ctx);
3562 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3563 ASSERT_TRUE(server_ctx);
3564
3565 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3566 ASSERT_TRUE(key);
3567 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3568 ASSERT_TRUE(leaf);
3569 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3570 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3571 chain.size(), key.get(), nullptr));
3572
3573 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3574 // configuration, certificate verification should fail.
3575 bssl::UniquePtr<SSL> client, server;
3576 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3577 server_ctx.get()));
3578
3579 // Whereas with a verifier, the connection should succeed.
3580 SSL_CTX_set_custom_verify(
3581 client_ctx.get(), SSL_VERIFY_PEER,
3582 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3583 return ssl_verify_ok;
3584 });
3585 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3586 server_ctx.get()));
3587}
3588
3589TEST(SSLTest, CustomVerify) {
3590 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3591 ASSERT_TRUE(client_ctx);
3592 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3593 ASSERT_TRUE(server_ctx);
3594
3595 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3596 ASSERT_TRUE(key);
3597 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3598 ASSERT_TRUE(leaf);
3599 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3600 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3601 chain.size(), key.get(), nullptr));
3602
3603 SSL_CTX_set_custom_verify(
3604 client_ctx.get(), SSL_VERIFY_PEER,
3605 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3606 return ssl_verify_ok;
3607 });
3608
3609 bssl::UniquePtr<SSL> client, server;
3610 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3611 server_ctx.get()));
3612
3613 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3614 // connection.
3615 SSL_CTX_set_custom_verify(
3616 client_ctx.get(), SSL_VERIFY_PEER,
3617 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3618 return ssl_verify_invalid;
3619 });
3620
3621 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3622 server_ctx.get()));
3623
3624 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3625 // connection.
3626 SSL_CTX_set_custom_verify(
3627 client_ctx.get(), SSL_VERIFY_NONE,
3628 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3629 return ssl_verify_invalid;
3630 });
3631
3632 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3633 server_ctx.get()));
3634}
3635
David Benjamin71dfad42017-07-16 17:27:39 -04003636TEST(SSLTest, ClientCABuffers) {
3637 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3638 ASSERT_TRUE(client_ctx);
3639 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3640 ASSERT_TRUE(server_ctx);
3641
3642 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3643 ASSERT_TRUE(key);
3644 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3645 ASSERT_TRUE(leaf);
3646 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3647 GetChainTestIntermediateBuffer();
3648 ASSERT_TRUE(intermediate);
3649 std::vector<CRYPTO_BUFFER *> chain = {
3650 leaf.get(),
3651 intermediate.get(),
3652 };
3653 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3654 chain.size(), key.get(), nullptr));
3655
3656 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3657 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3658 ASSERT_TRUE(ca_name);
3659 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3660 sk_CRYPTO_BUFFER_new_null());
3661 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003662 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003663 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3664
3665 // Configure client and server to accept all certificates.
3666 SSL_CTX_set_custom_verify(
3667 client_ctx.get(), SSL_VERIFY_PEER,
3668 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3669 return ssl_verify_ok;
3670 });
3671 SSL_CTX_set_custom_verify(
3672 server_ctx.get(), SSL_VERIFY_PEER,
3673 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3674 return ssl_verify_ok;
3675 });
3676
3677 bool cert_cb_called = false;
3678 SSL_CTX_set_cert_cb(
3679 client_ctx.get(),
3680 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003681 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003682 SSL_get0_server_requested_CAs(ssl);
3683 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3684 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3685 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3686 CRYPTO_BUFFER_len(peer_name)));
3687 *reinterpret_cast<bool *>(arg) = true;
3688 return 1;
3689 },
3690 &cert_cb_called);
3691
3692 bssl::UniquePtr<SSL> client, server;
3693 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003694 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003695 EXPECT_TRUE(cert_cb_called);
3696}
3697
David Benjamin91222b82017-03-09 20:10:56 -05003698// Configuring the empty cipher list, though an error, should still modify the
3699// configuration.
3700TEST(SSLTest, EmptyCipherList) {
3701 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3702 ASSERT_TRUE(ctx);
3703
3704 // Initially, the cipher list is not empty.
3705 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3706
3707 // Configuring the empty cipher list fails.
3708 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3709 ERR_clear_error();
3710
3711 // But the cipher list is still updated to empty.
3712 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3713}
3714
Adam Langley4c341d02017-03-08 19:33:21 -08003715// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3716// test |SSL_TICKET_AEAD_METHOD| can fail.
3717enum ssl_test_ticket_aead_failure_mode {
3718 ssl_test_ticket_aead_ok = 0,
3719 ssl_test_ticket_aead_seal_fail,
3720 ssl_test_ticket_aead_open_soft_fail,
3721 ssl_test_ticket_aead_open_hard_fail,
3722};
3723
3724struct ssl_test_ticket_aead_state {
3725 unsigned retry_count;
3726 ssl_test_ticket_aead_failure_mode failure_mode;
3727};
3728
3729static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3730 const CRYPTO_EX_DATA *from,
3731 void **from_d, int index,
3732 long argl, void *argp) {
3733 abort();
3734}
3735
3736static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3737 CRYPTO_EX_DATA *ad, int index,
3738 long argl, void *argp) {
3739 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3740 if (state == nullptr) {
3741 return;
3742 }
3743
3744 OPENSSL_free(state);
3745}
3746
3747static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3748static int g_ssl_test_ticket_aead_ex_index;
3749
3750static int ssl_test_ticket_aead_get_ex_index() {
3751 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3752 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3753 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3754 ssl_test_ticket_aead_ex_index_free);
3755 });
3756 return g_ssl_test_ticket_aead_ex_index;
3757}
3758
3759static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3760 return 1;
3761}
3762
3763static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3764 size_t max_out_len, const uint8_t *in,
3765 size_t in_len) {
3766 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3767 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3768
3769 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3770 max_out_len < in_len + 1) {
3771 return 0;
3772 }
3773
3774 OPENSSL_memmove(out, in, in_len);
3775 out[in_len] = 0xff;
3776 *out_len = in_len + 1;
3777
3778 return 1;
3779}
3780
3781static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3782 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3783 const uint8_t *in, size_t in_len) {
3784 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3785 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3786
3787 if (state->retry_count > 0) {
3788 state->retry_count--;
3789 return ssl_ticket_aead_retry;
3790 }
3791
3792 switch (state->failure_mode) {
3793 case ssl_test_ticket_aead_ok:
3794 break;
3795 case ssl_test_ticket_aead_seal_fail:
3796 // If |seal| failed then there shouldn't be any ticket to try and
3797 // decrypt.
3798 abort();
3799 break;
3800 case ssl_test_ticket_aead_open_soft_fail:
3801 return ssl_ticket_aead_ignore_ticket;
3802 case ssl_test_ticket_aead_open_hard_fail:
3803 return ssl_ticket_aead_error;
3804 }
3805
3806 if (in_len == 0 || in[in_len - 1] != 0xff) {
3807 return ssl_ticket_aead_ignore_ticket;
3808 }
3809
3810 if (max_out_len < in_len - 1) {
3811 return ssl_ticket_aead_error;
3812 }
3813
3814 OPENSSL_memmove(out, in, in_len - 1);
3815 *out_len = in_len - 1;
3816 return ssl_ticket_aead_success;
3817}
3818
3819static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3820 ssl_test_ticket_aead_max_overhead,
3821 ssl_test_ticket_aead_seal,
3822 ssl_test_ticket_aead_open,
3823};
3824
3825static void ConnectClientAndServerWithTicketMethod(
3826 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3827 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3828 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3829 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3830 ASSERT_TRUE(client);
3831 ASSERT_TRUE(server);
3832 SSL_set_connect_state(client.get());
3833 SSL_set_accept_state(server.get());
3834
3835 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3836 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3837 ASSERT_TRUE(state);
3838 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3839 state->retry_count = retry_count;
3840 state->failure_mode = failure_mode;
3841
3842 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3843 state));
3844
3845 SSL_set_session(client.get(), session);
3846
3847 BIO *bio1, *bio2;
3848 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3849
3850 // SSL_set_bio takes ownership.
3851 SSL_set_bio(client.get(), bio1, bio1);
3852 SSL_set_bio(server.get(), bio2, bio2);
3853
3854 if (CompleteHandshakes(client.get(), server.get())) {
3855 *out_client = std::move(client);
3856 *out_server = std::move(server);
3857 } else {
3858 out_client->reset();
3859 out_server->reset();
3860 }
3861}
3862
David Benjaminc9775322018-04-13 16:39:12 -04003863using TicketAEADMethodParam =
3864 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3865
Adam Langley4c341d02017-03-08 19:33:21 -08003866class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003867 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003868
3869TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003870 bssl::UniquePtr<SSL_CTX> server_ctx =
3871 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08003872 ASSERT_TRUE(server_ctx);
3873 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3874 ASSERT_TRUE(client_ctx);
3875
3876 const uint16_t version = testing::get<0>(GetParam());
3877 const unsigned retry_count = testing::get<1>(GetParam());
3878 const ssl_test_ticket_aead_failure_mode failure_mode =
3879 testing::get<2>(GetParam());
3880
Adam Langley4c341d02017-03-08 19:33:21 -08003881 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3882 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3883 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3884 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3885
3886 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3887 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3888 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3889 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003890 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003891
3892 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3893
3894 bssl::UniquePtr<SSL> client, server;
3895 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3896 server_ctx.get(), retry_count,
3897 failure_mode, nullptr);
3898 switch (failure_mode) {
3899 case ssl_test_ticket_aead_ok:
3900 case ssl_test_ticket_aead_open_hard_fail:
3901 case ssl_test_ticket_aead_open_soft_fail:
3902 ASSERT_TRUE(client);
3903 break;
3904 case ssl_test_ticket_aead_seal_fail:
3905 EXPECT_FALSE(client);
3906 return;
3907 }
3908 EXPECT_FALSE(SSL_session_reused(client.get()));
3909 EXPECT_FALSE(SSL_session_reused(server.get()));
3910
Steven Valdez777a2392019-02-21 11:30:47 -05003911 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05003912 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003913 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3914 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003915 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003916 switch (failure_mode) {
3917 case ssl_test_ticket_aead_ok:
3918 ASSERT_TRUE(client);
3919 EXPECT_TRUE(SSL_session_reused(client.get()));
3920 EXPECT_TRUE(SSL_session_reused(server.get()));
3921 break;
3922 case ssl_test_ticket_aead_seal_fail:
3923 abort();
3924 break;
3925 case ssl_test_ticket_aead_open_hard_fail:
3926 EXPECT_FALSE(client);
3927 break;
3928 case ssl_test_ticket_aead_open_soft_fail:
3929 ASSERT_TRUE(client);
3930 EXPECT_FALSE(SSL_session_reused(client.get()));
3931 EXPECT_FALSE(SSL_session_reused(server.get()));
3932 }
3933}
3934
David Benjaminc9775322018-04-13 16:39:12 -04003935std::string TicketAEADMethodParamToString(
3936 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3937 std::string ret = GetVersionName(std::get<0>(params.param));
3938 // GTest only allows alphanumeric characters and '_' in the parameter
3939 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3940 for (auto it = ret.begin(); it != ret.end();) {
3941 if (*it == '.' || *it == 'v') {
3942 it = ret.erase(it);
3943 } else {
3944 ++it;
3945 }
3946 }
3947 char retry_count[256];
3948 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3949 ret += "_";
3950 ret += retry_count;
3951 ret += "Retries_";
3952 switch (std::get<2>(params.param)) {
3953 case ssl_test_ticket_aead_ok:
3954 ret += "OK";
3955 break;
3956 case ssl_test_ticket_aead_seal_fail:
3957 ret += "SealFail";
3958 break;
3959 case ssl_test_ticket_aead_open_soft_fail:
3960 ret += "OpenSoftFail";
3961 break;
3962 case ssl_test_ticket_aead_open_hard_fail:
3963 ret += "OpenHardFail";
3964 break;
3965 }
3966 return ret;
3967}
3968
David Benjaminbe7006a2019-04-09 18:05:02 -05003969INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08003970 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003971 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3972 testing::Values(0, 1, 2),
3973 testing::Values(ssl_test_ticket_aead_ok,
3974 ssl_test_ticket_aead_seal_fail,
3975 ssl_test_ticket_aead_open_soft_fail,
3976 ssl_test_ticket_aead_open_hard_fail)),
3977 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003978
David Benjaminca743582017-06-15 17:51:35 -04003979TEST(SSLTest, SelectNextProto) {
3980 uint8_t *result;
3981 uint8_t result_len;
3982
3983 // If there is an overlap, it should be returned.
3984 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3985 SSL_select_next_proto(&result, &result_len,
3986 (const uint8_t *)"\1a\2bb\3ccc", 9,
3987 (const uint8_t *)"\1x\1y\1a\1z", 8));
3988 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3989
3990 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3991 SSL_select_next_proto(&result, &result_len,
3992 (const uint8_t *)"\1a\2bb\3ccc", 9,
3993 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3994 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3995
3996 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3997 SSL_select_next_proto(&result, &result_len,
3998 (const uint8_t *)"\1a\2bb\3ccc", 9,
3999 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4000 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4001
4002 // Peer preference order takes precedence over local.
4003 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4004 SSL_select_next_proto(&result, &result_len,
4005 (const uint8_t *)"\1a\2bb\3ccc", 9,
4006 (const uint8_t *)"\3ccc\2bb\1a", 9));
4007 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4008
4009 // If there is no overlap, return the first local protocol.
4010 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4011 SSL_select_next_proto(&result, &result_len,
4012 (const uint8_t *)"\1a\2bb\3ccc", 9,
4013 (const uint8_t *)"\1x\2yy\3zzz", 9));
4014 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4015
4016 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4017 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4018 (const uint8_t *)"\1x\2yy\3zzz", 9));
4019 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4020}
4021
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004022TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004023 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004024 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004025 ASSERT_TRUE(client_ctx);
4026 ASSERT_TRUE(server_ctx);
4027
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004028 bssl::UniquePtr<SSL> client, server;
4029 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004030 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004031
4032 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4033 std::vector<uint8_t> prefix(
4034 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004035 body(record.size()),
4036 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004037 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4038 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004039 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004040
4041 std::vector<uint8_t> sealed;
4042 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4043 sealed.insert(sealed.end(), body.begin(), body.end());
4044 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4045 std::vector<uint8_t> sealed_copy = sealed;
4046
4047 bssl::Span<uint8_t> plaintext;
4048 size_t record_len;
4049 uint8_t alert = 255;
4050 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4051 bssl::MakeSpan(sealed)),
4052 bssl::OpenRecordResult::kOK);
4053 EXPECT_EQ(record_len, sealed.size());
4054 EXPECT_EQ(plaintext, record);
4055 EXPECT_EQ(255, alert);
4056}
4057
4058TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004059 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004060 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004061 ASSERT_TRUE(client_ctx);
4062 ASSERT_TRUE(server_ctx);
4063
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004064 bssl::UniquePtr<SSL> client, server;
4065 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004066 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004067
4068 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4069 std::vector<uint8_t> record = plaintext;
4070 std::vector<uint8_t> prefix(
4071 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004072 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004073 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4074 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004075 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004076 record.insert(record.begin(), prefix.begin(), prefix.end());
4077 record.insert(record.end(), suffix.begin(), suffix.end());
4078
4079 bssl::Span<uint8_t> result;
4080 size_t record_len;
4081 uint8_t alert;
4082 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4083 bssl::MakeSpan(record)),
4084 bssl::OpenRecordResult::kOK);
4085 EXPECT_EQ(record_len, record.size());
4086 EXPECT_EQ(plaintext, result);
4087}
4088
4089TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004090 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004091 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004092 ASSERT_TRUE(client_ctx);
4093 ASSERT_TRUE(server_ctx);
4094
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004095 bssl::UniquePtr<SSL> client, server;
4096 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004097 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004098
4099 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4100 std::vector<uint8_t> record = plaintext;
4101 std::vector<uint8_t> prefix(
4102 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004103 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004104 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4105 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004106 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004107 record.insert(record.begin(), prefix.begin(), prefix.end());
4108 record.insert(record.end(), suffix.begin(), suffix.end());
4109 record.insert(record.end(), {5, 4, 3, 2, 1});
4110
4111 bssl::Span<uint8_t> result;
4112 size_t record_len;
4113 uint8_t alert;
4114 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4115 bssl::MakeSpan(record)),
4116 bssl::OpenRecordResult::kOK);
4117 EXPECT_EQ(record_len, record.size() - 5);
4118 EXPECT_EQ(plaintext, result);
4119}
4120
4121TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004122 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004123 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004124 ASSERT_TRUE(client_ctx);
4125 ASSERT_TRUE(server_ctx);
4126
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004127 bssl::UniquePtr<SSL> client, server;
4128 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004129 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004130
4131 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4132 std::vector<uint8_t> prefix(
4133 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004134 body(record.size()),
4135 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004136
4137 auto expect_err = []() {
4138 int err = ERR_get_error();
4139 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4140 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4141 ERR_clear_error();
4142 };
4143 EXPECT_FALSE(bssl::SealRecord(
4144 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004145 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004146 expect_err();
4147 EXPECT_FALSE(bssl::SealRecord(
4148 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004149 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004150 expect_err();
4151
4152 EXPECT_FALSE(
4153 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4154 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004155 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004156 expect_err();
4157 EXPECT_FALSE(
4158 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4159 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004160 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004161 expect_err();
4162
4163 EXPECT_FALSE(bssl::SealRecord(
4164 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004165 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004166 expect_err();
4167 EXPECT_FALSE(bssl::SealRecord(
4168 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004169 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004170 expect_err();
4171}
4172
David Benjamin617b8182017-08-29 15:33:10 -04004173// The client should gracefully handle no suitable ciphers being enabled.
4174TEST(SSLTest, NoCiphersAvailable) {
4175 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4176 ASSERT_TRUE(ctx);
4177
4178 // Configure |client_ctx| with a cipher list that does not intersect with its
4179 // version configuration.
4180 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4181 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4182 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4183
4184 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4185 ASSERT_TRUE(ssl);
4186 SSL_set_connect_state(ssl.get());
4187
4188 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4189 ASSERT_TRUE(rbio);
4190 ASSERT_TRUE(wbio);
4191 SSL_set0_rbio(ssl.get(), rbio.release());
4192 SSL_set0_wbio(ssl.get(), wbio.release());
4193
4194 int ret = SSL_do_handshake(ssl.get());
4195 EXPECT_EQ(-1, ret);
4196 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4197 uint32_t err = ERR_get_error();
4198 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4199 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4200}
4201
David Benjamina4bafd32017-10-03 15:06:29 -04004202TEST_P(SSLVersionTest, SessionVersion) {
4203 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4204 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4205
4206 bssl::UniquePtr<SSL_SESSION> session =
4207 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4208 ASSERT_TRUE(session);
4209 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4210
4211 // Sessions in TLS 1.3 and later should be single-use.
4212 EXPECT_EQ(version() == TLS1_3_VERSION,
4213 !!SSL_SESSION_should_be_single_use(session.get()));
4214
4215 // Making fake sessions for testing works.
4216 session.reset(SSL_SESSION_new(client_ctx_.get()));
4217 ASSERT_TRUE(session);
4218 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4219 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4220}
4221
David Benjaminfdb7a352017-10-12 17:34:18 -04004222TEST_P(SSLVersionTest, SSLPending) {
4223 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4224 ASSERT_TRUE(ssl);
4225 EXPECT_EQ(0, SSL_pending(ssl.get()));
4226
4227 ASSERT_TRUE(Connect());
4228 EXPECT_EQ(0, SSL_pending(client_.get()));
4229
4230 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4231 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4232 EXPECT_EQ(0, SSL_pending(client_.get()));
4233
4234 char buf[10];
4235 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4236 EXPECT_EQ(5, SSL_pending(client_.get()));
4237
4238 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4239 EXPECT_EQ(4, SSL_pending(client_.get()));
4240
4241 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4242 EXPECT_EQ(0, SSL_pending(client_.get()));
4243
4244 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4245 EXPECT_EQ(3, SSL_pending(client_.get()));
4246}
4247
David Benjamina031b612017-10-11 20:48:25 -04004248// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4249TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004250 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004251 ASSERT_TRUE(ctx);
4252 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4253 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4254
David Benjamina031b612017-10-11 20:48:25 -04004255 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4256
4257 bssl::UniquePtr<SSL> client, server;
4258 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4259
4260 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4261 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4262 return 0;
4263 });
4264
4265 // Send close_notify.
4266 EXPECT_EQ(0, SSL_shutdown(server.get()));
4267 EXPECT_EQ(0, SSL_shutdown(client.get()));
4268
4269 // Receive close_notify.
4270 EXPECT_EQ(1, SSL_shutdown(server.get()));
4271 EXPECT_EQ(1, SSL_shutdown(client.get()));
4272}
4273
David Benjamin6cc352e2017-11-02 17:21:39 -04004274TEST(SSLTest, SignatureAlgorithmProperties) {
4275 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4276 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4277 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4278
4279 EXPECT_EQ(EVP_PKEY_RSA,
4280 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4281 EXPECT_EQ(EVP_md5_sha1(),
4282 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4283 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4284
4285 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4286 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4287 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4288 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4289 EXPECT_FALSE(
4290 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4291
4292 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004293 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004294 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004295 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4296 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004297}
4298
Adam Langley85967952018-07-03 08:04:58 -07004299static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4300 size_t in_len) {
4301 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004302 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004303 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004304 }
4305 }
4306
4307 SSL_set_app_data(ssl, XORCompressFunc);
4308
Adam Langley85967952018-07-03 08:04:58 -07004309 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004310}
4311
Adam Langley85967952018-07-03 08:04:58 -07004312static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4313 size_t uncompressed_len, const uint8_t *in,
4314 size_t in_len) {
4315 if (in_len != uncompressed_len) {
4316 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004317 }
4318
4319 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004320 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4321 if (*out == nullptr) {
4322 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004323 }
4324
Adam Langley85967952018-07-03 08:04:58 -07004325 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004326 data[i] = in[i] ^ 0x55;
4327 }
4328
4329 SSL_set_app_data(ssl, XORDecompressFunc);
4330
Adam Langley85967952018-07-03 08:04:58 -07004331 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004332}
4333
4334TEST(SSLTest, CertCompression) {
4335 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004336 bssl::UniquePtr<SSL_CTX> server_ctx(
4337 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004338 ASSERT_TRUE(client_ctx);
4339 ASSERT_TRUE(server_ctx);
4340
Adam Langley0080d832018-06-07 16:39:49 -07004341 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4342 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4343 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4344 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4345 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4346 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4347
4348 bssl::UniquePtr<SSL> client, server;
4349 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4350 server_ctx.get()));
4351
4352 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4353 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4354}
4355
Adam Langleyddb57cf2018-01-26 09:17:53 -08004356void MoveBIOs(SSL *dest, SSL *src) {
4357 BIO *rbio = SSL_get_rbio(src);
4358 BIO_up_ref(rbio);
4359 SSL_set0_rbio(dest, rbio);
4360
4361 BIO *wbio = SSL_get_wbio(src);
4362 BIO_up_ref(wbio);
4363 SSL_set0_wbio(dest, wbio);
4364
4365 SSL_set0_rbio(src, nullptr);
4366 SSL_set0_wbio(src, nullptr);
4367}
4368
4369TEST(SSLTest, Handoff) {
4370 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4371 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004372 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4373 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004374 ASSERT_TRUE(client_ctx);
4375 ASSERT_TRUE(server_ctx);
4376 ASSERT_TRUE(handshaker_ctx);
4377
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004378 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4379 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004380 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004381 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004382 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004383 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004384
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004385 for (bool early_data : {false, true}) {
4386 SCOPED_TRACE(early_data);
4387 for (bool is_resume : {false, true}) {
4388 SCOPED_TRACE(is_resume);
4389 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004390 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4391 server_ctx.get()));
4392 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004393 if (is_resume) {
4394 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004395 SSL_set_session(client.get(), g_last_session.get());
4396 if (early_data) {
4397 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4398 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004399 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004400
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004401
4402 int client_ret = SSL_do_handshake(client.get());
4403 int client_err = SSL_get_error(client.get(), client_ret);
4404
4405 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004406 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004407 ASSERT_EQ(client_err, 0);
4408 EXPECT_TRUE(SSL_in_early_data(client.get()));
4409 // Attempt to write early data.
4410 byte_written = 43;
4411 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4412 } else {
4413 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4414 }
4415
4416 int server_ret = SSL_do_handshake(server.get());
4417 int server_err = SSL_get_error(server.get(), server_ret);
4418 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4419
4420 ScopedCBB cbb;
4421 Array<uint8_t> handoff;
4422 SSL_CLIENT_HELLO hello;
4423 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4424 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4425 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4426
4427 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4428 // Note split handshakes determines 0-RTT support, for both the current
4429 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4430 // no need to call |SSL_set_early_data_enabled| on |server|.
4431 SSL_set_early_data_enabled(handshaker.get(), 1);
4432 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4433
4434 MoveBIOs(handshaker.get(), server.get());
4435
4436 int handshake_ret = SSL_do_handshake(handshaker.get());
4437 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4438 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4439
4440 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004441 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004442 handshake_ret = SSL_do_handshake(handshaker.get());
4443 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4444 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4445
4446 ScopedCBB cbb_handback;
4447 Array<uint8_t> handback;
4448 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4449 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4450 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4451
4452 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4453 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4454
4455 MoveBIOs(server2.get(), handshaker.get());
4456 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4457 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4458
David Benjamin9b2cdb72021-04-01 23:21:53 -04004459 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004460 // In this case, one byte of early data has already been written above.
4461 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4462 } else {
4463 byte_written = 42;
4464 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4465 }
4466 uint8_t byte;
4467 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4468 EXPECT_EQ(byte_written, byte);
4469
4470 byte = 44;
4471 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4472 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4473 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004474 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004475 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004476}
4477
4478TEST(SSLTest, HandoffDeclined) {
4479 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004480 bssl::UniquePtr<SSL_CTX> server_ctx(
4481 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004482 ASSERT_TRUE(client_ctx);
4483 ASSERT_TRUE(server_ctx);
4484
4485 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4486 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4487
Adam Langleyddb57cf2018-01-26 09:17:53 -08004488 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004489 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4490 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004491
4492 int client_ret = SSL_do_handshake(client.get());
4493 int client_err = SSL_get_error(client.get(), client_ret);
4494 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4495
4496 int server_ret = SSL_do_handshake(server.get());
4497 int server_err = SSL_get_error(server.get(), server_ret);
4498 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4499
4500 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004501 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004502 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004503 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004504
4505 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4506
4507 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4508
4509 uint8_t byte = 42;
4510 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4511 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4512 EXPECT_EQ(42, byte);
4513
4514 byte = 43;
4515 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4516 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4517 EXPECT_EQ(43, byte);
4518}
4519
Adam Langley826ce152018-08-03 10:31:21 -07004520static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4521 std::string ret = "{";
4522
4523 for (uint16_t v : sigalgs) {
4524 if (ret.size() > 1) {
4525 ret += ", ";
4526 }
4527
4528 char buf[8];
4529 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4530 buf[sizeof(buf)-1] = 0;
4531 ret += std::string(buf);
4532 }
4533
4534 ret += "}";
4535 return ret;
4536}
4537
4538void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4539 Span<const uint16_t> actual) {
4540 bool matches = false;
4541 if (expected.size() == actual.size()) {
4542 matches = true;
4543
4544 for (size_t i = 0; i < expected.size(); i++) {
4545 if (expected[i] != actual[i]) {
4546 matches = false;
4547 break;
4548 }
4549 }
4550 }
4551
4552 if (!matches) {
4553 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4554 << " got: " << SigAlgsToString(actual);
4555 }
4556}
4557
4558TEST(SSLTest, SigAlgs) {
4559 static const struct {
4560 std::vector<int> input;
4561 bool ok;
4562 std::vector<uint16_t> expected;
4563 } kTests[] = {
4564 {{}, true, {}},
4565 {{1}, false, {}},
4566 {{1, 2, 3}, false, {}},
4567 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4568 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4569
4570 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4571 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4572 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4573 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4574 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4575 true,
4576 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4577 };
4578
4579 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4580
4581 unsigned n = 1;
4582 for (const auto &test : kTests) {
4583 SCOPED_TRACE(n++);
4584
4585 const bool ok =
4586 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4587 EXPECT_EQ(ok, test.ok);
4588
4589 if (!ok) {
4590 ERR_clear_error();
4591 }
4592
4593 if (!test.ok) {
4594 continue;
4595 }
4596
4597 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4598 }
4599}
4600
4601TEST(SSLTest, SigAlgsList) {
4602 static const struct {
4603 const char *input;
4604 bool ok;
4605 std::vector<uint16_t> expected;
4606 } kTests[] = {
4607 {"", false, {}},
4608 {":", false, {}},
4609 {"+", false, {}},
4610 {"RSA", false, {}},
4611 {"RSA+", false, {}},
4612 {"RSA+SHA256:", false, {}},
4613 {":RSA+SHA256:", false, {}},
4614 {":RSA+SHA256+:", false, {}},
4615 {"!", false, {}},
4616 {"\x01", false, {}},
4617 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4618 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4619
4620 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4621 {"RSA+SHA256:ed25519",
4622 true,
4623 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4624 {"ECDSA+SHA256:RSA+SHA512",
4625 true,
4626 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4627 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4628 true,
4629 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4630 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4631 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4632 };
4633
4634 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4635
4636 unsigned n = 1;
4637 for (const auto &test : kTests) {
4638 SCOPED_TRACE(n++);
4639
4640 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4641 EXPECT_EQ(ok, test.ok);
4642
4643 if (!ok) {
4644 if (test.ok) {
4645 ERR_print_errors_fp(stderr);
4646 }
4647 ERR_clear_error();
4648 }
4649
4650 if (!test.ok) {
4651 continue;
4652 }
4653
4654 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4655 }
4656}
4657
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004658TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4659 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4660 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4661
4662 // handoff is a handoff message that has been artificially modified to pretend
4663 // that only cipher 0x0A is supported. When it is applied to |server|, all
4664 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004665 //
4666 // To make a new one of these, try sticking this in the |Handoff| test above:
4667 //
4668 // hexdump(stderr, "", handoff.data(), handoff.size());
4669 // sed -e 's/\(..\)/0x\1, /g'
4670 //
4671 // and modify serialize_features() to emit only cipher 0x0A.
4672
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004673 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004674 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4675 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4676 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4677 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4678 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004679 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4680 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004681 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4682 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4683 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4684 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4685 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4686 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4687 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004688 };
4689
4690 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4691 ASSERT_TRUE(
4692 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4693 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4694}
4695
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004696TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4697 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4698 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4699
4700 // handoff is a handoff message that has been artificially modified to pretend
4701 // that only one curve is supported. When it is applied to |server|, all
4702 // curves but that one should be removed.
4703 //
4704 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4705 // these.
4706 uint8_t handoff[] = {
4707 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4708 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4709 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4710 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4711 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4712 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4713 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4714 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4715 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4716 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4717 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4718 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4719 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4720 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4721 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4722 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4723 0x02, 0x00, 0x17,
4724 };
4725
4726 // The zero length means that the default list of groups is used.
4727 EXPECT_EQ(0u, server->config->supported_group_list.size());
4728 ASSERT_TRUE(
4729 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4730 EXPECT_EQ(1u, server->config->supported_group_list.size());
4731}
4732
Adam Langleyba9ad662018-12-17 13:59:38 -08004733TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4734 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4735 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04004736 bssl::UniquePtr<SSL_CTX> server_ctx(
4737 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08004738 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4739 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08004740
4741 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4742 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4743 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4744
4745 bssl::UniquePtr<SSL> client, server;
4746 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4747 server_ctx.get()));
4748
4749 BIO *client_wbio = SSL_get_wbio(client.get());
4750 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4751 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4752 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4753 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4754 EXPECT_NE(0u, BIO_wpending(client_wbio));
4755}
4756
David Benjamin5869eb32018-07-17 00:59:45 -04004757TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4758 // Configure the server to request client certificates.
4759 SSL_CTX_set_custom_verify(
4760 server_ctx_.get(), SSL_VERIFY_PEER,
4761 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4762
4763 // Configure the client to reject the server certificate.
4764 SSL_CTX_set_custom_verify(
4765 client_ctx_.get(), SSL_VERIFY_PEER,
4766 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4767
4768 // cert_cb should not be called. Verification should fail first.
4769 SSL_CTX_set_cert_cb(client_ctx_.get(),
4770 [](SSL *ssl, void *arg) {
4771 ADD_FAILURE() << "cert_cb unexpectedly called";
4772 return 0;
4773 },
4774 nullptr);
4775
4776 bssl::UniquePtr<SSL> client, server;
4777 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4778 server_ctx_.get()));
4779}
4780
David Benjamin492c9aa2018-08-31 16:35:22 -05004781// Test that ticket-based sessions on the client get fake session IDs.
4782TEST_P(SSLVersionTest, FakeIDsForTickets) {
4783 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4784 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4785
4786 bssl::UniquePtr<SSL_SESSION> session =
4787 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4788 ASSERT_TRUE(session);
4789
4790 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4791 unsigned session_id_length;
4792 SSL_SESSION_get_id(session.get(), &session_id_length);
4793 EXPECT_NE(session_id_length, 0u);
4794}
4795
David Benjamin6c04bd12018-07-19 18:13:09 -04004796// These tests test multi-threaded behavior. They are intended to run with
4797// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004798#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004799TEST_P(SSLVersionTest, SessionCacheThreads) {
4800 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4801 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4802 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4803
4804 if (version() == TLS1_3_VERSION) {
4805 // Our TLS 1.3 implementation does not support stateful resumption.
4806 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4807 return;
4808 }
4809
4810 // Establish two client sessions to test with.
4811 bssl::UniquePtr<SSL_SESSION> session1 =
4812 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4813 ASSERT_TRUE(session1);
4814 bssl::UniquePtr<SSL_SESSION> session2 =
4815 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4816 ASSERT_TRUE(session2);
4817
4818 auto connect_with_session = [&](SSL_SESSION *session) {
4819 ClientConfig config;
4820 config.session = session;
4821 UniquePtr<SSL> client, server;
4822 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4823 server_ctx_.get(), config));
4824 };
4825
4826 // Resume sessions in parallel with establishing new ones.
4827 {
4828 std::vector<std::thread> threads;
4829 threads.emplace_back([&] { connect_with_session(nullptr); });
4830 threads.emplace_back([&] { connect_with_session(nullptr); });
4831 threads.emplace_back([&] { connect_with_session(session1.get()); });
4832 threads.emplace_back([&] { connect_with_session(session1.get()); });
4833 threads.emplace_back([&] { connect_with_session(session2.get()); });
4834 threads.emplace_back([&] { connect_with_session(session2.get()); });
4835 for (auto &thread : threads) {
4836 thread.join();
4837 }
4838 }
4839
4840 // Hit the maximum session cache size across multiple threads
4841 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4842 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4843 {
4844 std::vector<std::thread> threads;
4845 for (int i = 0; i < 4; i++) {
4846 threads.emplace_back([&]() {
4847 connect_with_session(nullptr);
4848 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4849 });
4850 }
4851 for (auto &thread : threads) {
4852 thread.join();
4853 }
4854 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4855 }
4856}
4857
4858TEST_P(SSLVersionTest, SessionTicketThreads) {
4859 for (bool renew_ticket : {false, true}) {
4860 SCOPED_TRACE(renew_ticket);
4861 ResetContexts();
4862 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4863 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4864 if (renew_ticket) {
4865 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4866 }
4867
4868 // Establish two client sessions to test with.
4869 bssl::UniquePtr<SSL_SESSION> session1 =
4870 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4871 ASSERT_TRUE(session1);
4872 bssl::UniquePtr<SSL_SESSION> session2 =
4873 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4874 ASSERT_TRUE(session2);
4875
4876 auto connect_with_session = [&](SSL_SESSION *session) {
4877 ClientConfig config;
4878 config.session = session;
4879 UniquePtr<SSL> client, server;
4880 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4881 server_ctx_.get(), config));
4882 };
4883
4884 // Resume sessions in parallel with establishing new ones.
4885 {
4886 std::vector<std::thread> threads;
4887 threads.emplace_back([&] { connect_with_session(nullptr); });
4888 threads.emplace_back([&] { connect_with_session(nullptr); });
4889 threads.emplace_back([&] { connect_with_session(session1.get()); });
4890 threads.emplace_back([&] { connect_with_session(session1.get()); });
4891 threads.emplace_back([&] { connect_with_session(session2.get()); });
4892 threads.emplace_back([&] { connect_with_session(session2.get()); });
4893 for (auto &thread : threads) {
4894 thread.join();
4895 }
4896 }
4897 }
4898}
4899
4900// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4901TEST(SSLTest, GetCertificateThreads) {
4902 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4903 ASSERT_TRUE(ctx);
4904 bssl::UniquePtr<X509> cert = GetTestCertificate();
4905 ASSERT_TRUE(cert);
4906 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4907
4908 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4909 // threads concurrently. It originally was an immutable operation. Now we
4910 // implement it with a thread-safe cache, so it is worth testing.
4911 X509 *cert2_thread;
4912 std::thread thread(
4913 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4914 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4915 thread.join();
4916
4917 EXPECT_EQ(cert2, cert2_thread);
4918 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4919}
David Benjamin4cce9552018-12-13 12:20:54 -06004920
4921// Functions which access properties on the negotiated session are thread-safe
4922// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4923// performing stateful resumption will share an underlying SSL_SESSION object,
4924// potentially across threads.
4925TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4926 if (version() == TLS1_3_VERSION) {
4927 // Our TLS 1.3 implementation does not support stateful resumption.
4928 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4929 return;
4930 }
4931
4932 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4933 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4934 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4935
4936 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4937 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4938
4939 // Configure mutual authentication, so we have more session state.
4940 SSL_CTX_set_custom_verify(
4941 client_ctx_.get(), SSL_VERIFY_PEER,
4942 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4943 SSL_CTX_set_custom_verify(
4944 server_ctx_.get(), SSL_VERIFY_PEER,
4945 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4946
4947 // Establish a client session to test with.
4948 bssl::UniquePtr<SSL_SESSION> session =
4949 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4950 ASSERT_TRUE(session);
4951
4952 // Resume with it twice.
4953 UniquePtr<SSL> ssls[4];
4954 ClientConfig config;
4955 config.session = session.get();
4956 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4957 server_ctx_.get(), config));
4958 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4959 server_ctx_.get(), config));
4960
4961 // Read properties in parallel.
4962 auto read_properties = [](const SSL *ssl) {
4963 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4964 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4965 EXPECT_TRUE(peer);
4966 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4967 EXPECT_TRUE(SSL_get_curve_id(ssl));
4968 };
4969
4970 std::vector<std::thread> threads;
4971 for (const auto &ssl_ptr : ssls) {
4972 const SSL *ssl = ssl_ptr.get();
4973 threads.emplace_back([=] { read_properties(ssl); });
4974 }
4975 for (auto &thread : threads) {
4976 thread.join();
4977 }
4978}
David Benjamina486c6c2019-03-28 18:32:38 -05004979#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04004980
Steven Valdezc8e0f902018-07-14 11:23:01 -04004981constexpr size_t kNumQUICLevels = 4;
4982static_assert(ssl_encryption_initial < kNumQUICLevels,
4983 "kNumQUICLevels is wrong");
4984static_assert(ssl_encryption_early_data < kNumQUICLevels,
4985 "kNumQUICLevels is wrong");
4986static_assert(ssl_encryption_handshake < kNumQUICLevels,
4987 "kNumQUICLevels is wrong");
4988static_assert(ssl_encryption_application < kNumQUICLevels,
4989 "kNumQUICLevels is wrong");
4990
David Benjamin1e859052020-02-09 16:04:58 -05004991const char *LevelToString(ssl_encryption_level_t level) {
4992 switch (level) {
4993 case ssl_encryption_initial:
4994 return "initial";
4995 case ssl_encryption_early_data:
4996 return "early data";
4997 case ssl_encryption_handshake:
4998 return "handshake";
4999 case ssl_encryption_application:
5000 return "application";
5001 }
5002 return "<unknown>";
5003}
5004
Steven Valdezc8e0f902018-07-14 11:23:01 -04005005class MockQUICTransport {
5006 public:
David Benjamind6343572019-08-15 17:29:02 -04005007 enum class Role { kClient, kServer };
5008
5009 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005010 // The caller is expected to configure initial secrets.
5011 levels_[ssl_encryption_initial].write_secret = {1};
5012 levels_[ssl_encryption_initial].read_secret = {1};
5013 }
5014
5015 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5016
5017 bool has_alert() const { return has_alert_; }
5018 ssl_encryption_level_t alert_level() const { return alert_level_; }
5019 uint8_t alert() const { return alert_; }
5020
5021 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5022 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005023 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5024 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005025 }
5026
David Benjamin1e859052020-02-09 16:04:58 -05005027 bool HasReadSecret(ssl_encryption_level_t level) const {
5028 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005029 }
5030
David Benjamin1e859052020-02-09 16:04:58 -05005031 bool HasWriteSecret(ssl_encryption_level_t level) const {
5032 return !levels_[level].write_secret.empty();
5033 }
5034
David Benjamin5298ef92020-03-13 12:17:30 -04005035 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5036
David Benjamin1e859052020-02-09 16:04:58 -05005037 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5038 Span<const uint8_t> secret) {
5039 if (HasReadSecret(level)) {
5040 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5041 return false;
5042 }
5043
5044 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5045 ADD_FAILURE() << "Unexpected early data read secret";
5046 return false;
5047 }
5048
5049 ssl_encryption_level_t ack_level =
5050 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5051 if (!HasWriteSecret(ack_level)) {
5052 ADD_FAILURE() << LevelToString(level)
5053 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005054 return false;
5055 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005056
5057 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005058 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005059 return false;
5060 }
5061
David Benjamin1e859052020-02-09 16:04:58 -05005062 if (level != ssl_encryption_early_data &&
5063 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5064 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005065 return false;
5066 }
David Benjamind6343572019-08-15 17:29:02 -04005067
David Benjamin1e859052020-02-09 16:04:58 -05005068 levels_[level].read_secret.assign(secret.begin(), secret.end());
5069 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5070 return true;
5071 }
5072
5073 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5074 Span<const uint8_t> secret) {
5075 if (HasWriteSecret(level)) {
5076 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005077 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005078 }
David Benjamind6343572019-08-15 17:29:02 -04005079
David Benjamin1e859052020-02-09 16:04:58 -05005080 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5081 ADD_FAILURE() << "Unexpected early data write secret";
5082 return false;
5083 }
5084
5085 if (cipher == nullptr) {
5086 ADD_FAILURE() << "Unexpected null cipher";
5087 return false;
5088 }
5089
5090 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005091 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005092 return true;
5093 }
5094
5095 bool WriteHandshakeData(ssl_encryption_level_t level,
5096 Span<const uint8_t> data) {
5097 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005098 ADD_FAILURE() << LevelToString(level)
5099 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005100 return false;
5101 }
David Benjamin5298ef92020-03-13 12:17:30 -04005102
5103 // Although the levels are conceptually separate, BoringSSL finishes writing
5104 // data from a previous level before installing keys for the next level.
5105 if (!allow_out_of_order_writes_) {
5106 switch (level) {
5107 case ssl_encryption_early_data:
5108 ADD_FAILURE() << "unexpected handshake data at early data level";
5109 return false;
5110 case ssl_encryption_initial:
5111 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5112 ADD_FAILURE()
5113 << LevelToString(level)
5114 << " handshake data written after handshake keys installed";
5115 return false;
5116 }
5117 OPENSSL_FALLTHROUGH;
5118 case ssl_encryption_handshake:
5119 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5120 ADD_FAILURE()
5121 << LevelToString(level)
5122 << " handshake data written after application keys installed";
5123 return false;
5124 }
5125 OPENSSL_FALLTHROUGH;
5126 case ssl_encryption_application:
5127 break;
5128 }
5129 }
5130
Steven Valdezc8e0f902018-07-14 11:23:01 -04005131 levels_[level].write_data.insert(levels_[level].write_data.end(),
5132 data.begin(), data.end());
5133 return true;
5134 }
5135
5136 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5137 if (has_alert_) {
5138 ADD_FAILURE() << "duplicate alert sent";
5139 return false;
5140 }
5141
5142 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005143 ADD_FAILURE() << LevelToString(level)
5144 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005145 return false;
5146 }
5147
5148 has_alert_ = true;
5149 alert_level_ = level;
5150 alert_ = alert_value;
5151 return true;
5152 }
5153
5154 bool ReadHandshakeData(std::vector<uint8_t> *out,
5155 ssl_encryption_level_t level,
5156 size_t num = std::numeric_limits<size_t>::max()) {
5157 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005158 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005159 return false;
5160 }
5161 // The peer may not have configured any keys yet.
5162 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005163 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005164 return true;
5165 }
5166 // Check the peer computed the same key.
5167 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005168 ADD_FAILURE() << "peer write key does not match read key in level "
5169 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005170 return false;
5171 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005172 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005173 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005174 return false;
5175 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005176 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5177 num = std::min(num, peer_data->size());
5178 out->assign(peer_data->begin(), peer_data->begin() + num);
5179 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5180 return true;
5181 }
5182
5183 private:
David Benjamind6343572019-08-15 17:29:02 -04005184 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005185 MockQUICTransport *peer_ = nullptr;
5186
David Benjamin5298ef92020-03-13 12:17:30 -04005187 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005188 bool has_alert_ = false;
5189 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5190 uint8_t alert_ = 0;
5191
5192 struct Level {
5193 std::vector<uint8_t> write_data;
5194 std::vector<uint8_t> write_secret;
5195 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005196 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005197 };
5198 Level levels_[kNumQUICLevels];
5199};
5200
5201class MockQUICTransportPair {
5202 public:
David Benjamind6343572019-08-15 17:29:02 -04005203 MockQUICTransportPair()
5204 : client_(MockQUICTransport::Role::kClient),
5205 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005206 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005207 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005208 }
5209
5210 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005211 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005212 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005213 }
5214
5215 MockQUICTransport *client() { return &client_; }
5216 MockQUICTransport *server() { return &server_; }
5217
5218 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005219 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5220 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5221 return client_.PeerSecretsMatch(level) &&
5222 client_.HasWriteSecret(level) &&
5223 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005224 }
5225
5226 private:
5227 MockQUICTransport client_;
5228 MockQUICTransport server_;
5229};
5230
5231class QUICMethodTest : public testing::Test {
5232 protected:
5233 void SetUp() override {
5234 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005235 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005236 ASSERT_TRUE(client_ctx_);
5237 ASSERT_TRUE(server_ctx_);
5238
Steven Valdezc8e0f902018-07-14 11:23:01 -04005239 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5240 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5241 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5242 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005243
5244 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5245 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5246 sizeof(kALPNProtos)),
5247 0);
5248 SSL_CTX_set_alpn_select_cb(
5249 server_ctx_.get(),
5250 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5251 unsigned in_len, void *arg) -> int {
5252 return SSL_select_next_proto(
5253 const_cast<uint8_t **>(out), out_len, in, in_len,
5254 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5255 ? SSL_TLSEXT_ERR_OK
5256 : SSL_TLSEXT_ERR_NOACK;
5257 },
5258 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005259 }
5260
5261 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5262 return ex_data_.Get(ssl);
5263 }
5264
5265 static bool ProvideHandshakeData(
5266 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5267 MockQUICTransport *transport = TransportFromSSL(ssl);
5268 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5269 std::vector<uint8_t> data;
5270 return transport->ReadHandshakeData(&data, level, num) &&
5271 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5272 }
5273
David Benjamin5298ef92020-03-13 12:17:30 -04005274 void AllowOutOfOrderWrites() {
5275 allow_out_of_order_writes_ = true;
5276 }
5277
Steven Valdezc8e0f902018-07-14 11:23:01 -04005278 bool CreateClientAndServer() {
5279 client_.reset(SSL_new(client_ctx_.get()));
5280 server_.reset(SSL_new(server_ctx_.get()));
5281 if (!client_ || !server_) {
5282 return false;
5283 }
5284
5285 SSL_set_connect_state(client_.get());
5286 SSL_set_accept_state(server_.get());
5287
David Benjamind6343572019-08-15 17:29:02 -04005288 transport_.reset(new MockQUICTransportPair);
5289 ex_data_.Set(client_.get(), transport_->client());
5290 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005291 if (allow_out_of_order_writes_) {
5292 transport_->client()->AllowOutOfOrderWrites();
5293 transport_->server()->AllowOutOfOrderWrites();
5294 }
Nick Harper7c522992020-04-30 14:15:49 -07005295 static const uint8_t client_transport_params[] = {0};
5296 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5297 sizeof(client_transport_params)) ||
5298 !SSL_set_quic_transport_params(server_.get(),
5299 server_transport_params_.data(),
5300 server_transport_params_.size()) ||
5301 !SSL_set_quic_early_data_context(
5302 server_.get(), server_quic_early_data_context_.data(),
5303 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005304 return false;
5305 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005306 return true;
5307 }
5308
Nick Harper72cff812020-03-26 18:06:16 -07005309 enum class ExpectedError {
5310 kNoError,
5311 kClientError,
5312 kServerError,
5313 };
5314
David Benjamind6343572019-08-15 17:29:02 -04005315 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5316 // |server_| until each completes once. It returns true on success and false
5317 // on failure.
5318 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005319 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5320 }
5321
5322 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5323 // once. If |expect_client_error| is true, it will return true only if the
5324 // client handshake failed. Otherwise, it returns true if both handshakes
5325 // succeed and false otherwise.
5326 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005327 bool client_done = false, server_done = false;
5328 while (!client_done || !server_done) {
5329 if (!client_done) {
5330 if (!ProvideHandshakeData(client_.get())) {
5331 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5332 return false;
5333 }
5334 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005335 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005336 if (client_ret == 1) {
5337 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005338 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005339 if (expected_error == ExpectedError::kClientError) {
5340 return true;
5341 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005342 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5343 << client_err;
5344 return false;
David Benjamind6343572019-08-15 17:29:02 -04005345 }
5346 }
5347
5348 if (!server_done) {
5349 if (!ProvideHandshakeData(server_.get())) {
5350 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5351 return false;
5352 }
5353 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005354 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005355 if (server_ret == 1) {
5356 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005357 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005358 if (expected_error == ExpectedError::kServerError) {
5359 return true;
5360 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005361 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5362 << server_err;
5363 return false;
David Benjamind6343572019-08-15 17:29:02 -04005364 }
5365 }
5366 }
Nick Harper72cff812020-03-26 18:06:16 -07005367 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005368 }
5369
5370 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5371 g_last_session = nullptr;
5372 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5373 if (!CreateClientAndServer() ||
5374 !CompleteHandshakesForQUIC()) {
5375 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005376 }
5377
David Benjamind6343572019-08-15 17:29:02 -04005378 // The server sent NewSessionTicket messages in the handshake.
5379 if (!ProvideHandshakeData(client_.get()) ||
5380 !SSL_process_quic_post_handshake(client_.get())) {
5381 return nullptr;
5382 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005383
David Benjamind6343572019-08-15 17:29:02 -04005384 return std::move(g_last_session);
5385 }
5386
5387 void ExpectHandshakeSuccess() {
5388 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5389 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5390 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5391 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5392 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5393 EXPECT_FALSE(transport_->client()->has_alert());
5394 EXPECT_FALSE(transport_->server()->has_alert());
5395
5396 // SSL_do_handshake is now idempotent.
5397 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5398 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005399 }
5400
David Benjamin1e859052020-02-09 16:04:58 -05005401 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5402 // the test.
5403 SSL_QUIC_METHOD DefaultQUICMethod() {
5404 return SSL_QUIC_METHOD{
5405 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5406 FlushFlightCallback, SendAlertCallback,
5407 };
5408 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005409
David Benjamin1e859052020-02-09 16:04:58 -05005410 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5411 const SSL_CIPHER *cipher,
5412 const uint8_t *secret, size_t secret_len) {
5413 return TransportFromSSL(ssl)->SetReadSecret(
5414 level, cipher, MakeConstSpan(secret, secret_len));
5415 }
5416
5417 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5418 const SSL_CIPHER *cipher,
5419 const uint8_t *secret, size_t secret_len) {
5420 return TransportFromSSL(ssl)->SetWriteSecret(
5421 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005422 }
5423
David Benjamincc9d9352018-10-30 19:45:22 -05005424 static int AddHandshakeDataCallback(SSL *ssl,
5425 enum ssl_encryption_level_t level,
5426 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005427 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5428 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5429 MakeConstSpan(data, len));
5430 }
5431
5432 static int FlushFlightCallback(SSL *ssl) { return 1; }
5433
5434 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5435 uint8_t alert) {
5436 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5437 return TransportFromSSL(ssl)->SendAlert(level, alert);
5438 }
5439
5440 bssl::UniquePtr<SSL_CTX> client_ctx_;
5441 bssl::UniquePtr<SSL_CTX> server_ctx_;
5442
5443 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005444 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005445
5446 bssl::UniquePtr<SSL> client_;
5447 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005448
Nick Harper7c522992020-04-30 14:15:49 -07005449 std::vector<uint8_t> server_transport_params_ = {1};
5450 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5451
David Benjamin5298ef92020-03-13 12:17:30 -04005452 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005453};
5454
5455UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5456
David Benjaminfd863b62019-07-25 13:51:32 -04005457// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005458TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005459 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005460
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005461 g_last_session = nullptr;
5462
5463 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5464 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005465 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5466 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005467
Steven Valdezc8e0f902018-07-14 11:23:01 -04005468 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005469 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005470
David Benjamind6343572019-08-15 17:29:02 -04005471 ExpectHandshakeSuccess();
5472 EXPECT_FALSE(SSL_session_reused(client_.get()));
5473 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005474
5475 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005476 EXPECT_FALSE(g_last_session);
5477 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5478 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5479 EXPECT_TRUE(g_last_session);
5480
5481 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005482 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005483 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5484 SSL_set_session(client_.get(), session.get());
5485
David Benjamind6343572019-08-15 17:29:02 -04005486 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005487
David Benjamind6343572019-08-15 17:29:02 -04005488 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005489 EXPECT_TRUE(SSL_session_reused(client_.get()));
5490 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005491}
5492
David Benjaminfd863b62019-07-25 13:51:32 -04005493// Test that HelloRetryRequest in QUIC works.
5494TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05005495 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04005496
5497 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5498 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5499
5500 // BoringSSL predicts the most preferred curve, so using different preferences
5501 // will trigger HelloRetryRequest.
5502 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5503 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5504 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5505 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5506 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5507 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5508
5509 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005510 ASSERT_TRUE(CompleteHandshakesForQUIC());
5511 ExpectHandshakeSuccess();
5512}
David Benjaminfd863b62019-07-25 13:51:32 -04005513
Nick Harpere32549e2020-05-06 14:27:11 -07005514// Test that the client does not send a legacy_session_id in the ClientHello.
5515TEST_F(QUICMethodTest, NoLegacySessionId) {
5516 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5517
5518 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5519 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5520 // Check that the session ID length is 0 in an early callback.
5521 SSL_CTX_set_select_certificate_cb(
5522 server_ctx_.get(),
5523 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
5524 EXPECT_EQ(client_hello->session_id_len, 0u);
5525 return ssl_select_cert_success;
5526 });
5527
5528 ASSERT_TRUE(CreateClientAndServer());
5529 ASSERT_TRUE(CompleteHandshakesForQUIC());
5530
5531 ExpectHandshakeSuccess();
5532}
5533
David Benjamin1e859052020-02-09 16:04:58 -05005534// Test that, even in a 1-RTT handshake, the server installs keys at the right
5535// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
5536TEST_F(QUICMethodTest, HalfRTTKeys) {
5537 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5538
5539 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5540 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5541 ASSERT_TRUE(CreateClientAndServer());
5542
5543 // The client sends ClientHello.
5544 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5545 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
5546
5547 // The server reads ClientHello and sends ServerHello..Finished.
5548 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5549 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5550 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5551
5552 // At this point, the server has half-RTT write keys, but it cannot access
5553 // 1-RTT read keys until client Finished.
5554 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5555 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5556
5557 // Finish up the client and server handshakes.
5558 ASSERT_TRUE(CompleteHandshakesForQUIC());
5559
5560 // Both sides can now exchange 1-RTT data.
5561 ExpectHandshakeSuccess();
5562}
5563
David Benjamind6343572019-08-15 17:29:02 -04005564TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05005565 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005566
5567 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5568 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5569 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5570 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5571 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5572
5573 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5574 ASSERT_TRUE(session);
5575
5576 ASSERT_TRUE(CreateClientAndServer());
5577 SSL_set_session(client_.get(), session.get());
5578
5579 // The client handshake should return immediately into the early data state.
5580 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5581 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5582 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005583 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005584
5585 // The server will consume the ClientHello and also enter the early data
5586 // state.
5587 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5588 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5589 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5590 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05005591 // At this point, the server has half-RTT write keys, but it cannot access
5592 // 1-RTT read keys until client Finished.
5593 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5594 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04005595
5596 // Finish up the client and server handshakes.
5597 ASSERT_TRUE(CompleteHandshakesForQUIC());
5598
5599 // Both sides can now exchange 1-RTT data.
5600 ExpectHandshakeSuccess();
5601 EXPECT_TRUE(SSL_session_reused(client_.get()));
5602 EXPECT_TRUE(SSL_session_reused(server_.get()));
5603 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5604 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5605 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5606 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07005607
5608 // Finish handling post-handshake messages after the first 0-RTT resumption.
5609 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
5610 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
5611
5612 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
5613 // accepted again.
5614 ASSERT_TRUE(CreateClientAndServer());
5615 SSL_set_session(client_.get(), g_last_session.get());
5616
5617 // The client handshake should return immediately into the early data state.
5618 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5619 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5620 // The transport should have keys for sending 0-RTT data.
5621 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
5622
5623 // The server will consume the ClientHello and also enter the early data
5624 // state.
5625 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5626 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5627 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5628 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5629 // At this point, the server has half-RTT write keys, but it cannot access
5630 // 1-RTT read keys until client Finished.
5631 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5632 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5633
5634 // Finish up the client and server handshakes.
5635 ASSERT_TRUE(CompleteHandshakesForQUIC());
5636
5637 // Both sides can now exchange 1-RTT data.
5638 ExpectHandshakeSuccess();
5639 EXPECT_TRUE(SSL_session_reused(client_.get()));
5640 EXPECT_TRUE(SSL_session_reused(server_.get()));
5641 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5642 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5643 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5644 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5645 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
5646 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04005647}
5648
Nick Harper7c522992020-04-30 14:15:49 -07005649TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
5650 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5651
5652 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5653 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5654 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5655 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5656 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5657
5658
5659 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5660 ASSERT_TRUE(session);
5661
Nick Harper85194322020-05-20 16:59:29 -07005662 ASSERT_TRUE(CreateClientAndServer());
5663 static const uint8_t new_context[] = {4};
5664 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
5665 sizeof(new_context)));
5666 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07005667
Nick Harper85194322020-05-20 16:59:29 -07005668 // The client handshake should return immediately into the early data
5669 // state.
5670 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5671 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5672 // The transport should have keys for sending 0-RTT data.
5673 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005674
Nick Harper85194322020-05-20 16:59:29 -07005675 // The server will consume the ClientHello, but it will not accept 0-RTT.
5676 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5677 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5678 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5679 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5680 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005681
Nick Harper85194322020-05-20 16:59:29 -07005682 // The client consumes the server response and signals 0-RTT rejection.
5683 for (;;) {
5684 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5685 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5686 int err = SSL_get_error(client_.get(), -1);
5687 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5688 break;
Nick Harper7c522992020-04-30 14:15:49 -07005689 }
Nick Harper85194322020-05-20 16:59:29 -07005690 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07005691 }
Nick Harper85194322020-05-20 16:59:29 -07005692
5693 // As in TLS over TCP, 0-RTT rejection is sticky.
5694 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5695 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5696
5697 // Finish up the client and server handshakes.
5698 SSL_reset_early_data_reject(client_.get());
5699 ASSERT_TRUE(CompleteHandshakesForQUIC());
5700
5701 // Both sides can now exchange 1-RTT data.
5702 ExpectHandshakeSuccess();
5703 EXPECT_TRUE(SSL_session_reused(client_.get()));
5704 EXPECT_TRUE(SSL_session_reused(server_.get()));
5705 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5706 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5707 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5708 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
5709}
5710
5711TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
5712 server_quic_early_data_context_ = {};
5713 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5714
5715 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5716 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5717 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5718 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5719 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5720
5721 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5722 ASSERT_TRUE(session);
5723 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07005724}
5725
David Benjamind6343572019-08-15 17:29:02 -04005726TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05005727 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005728
5729 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5730 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5731 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5732 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5733 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5734
5735 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5736 ASSERT_TRUE(session);
5737
5738 for (bool reject_hrr : {false, true}) {
5739 SCOPED_TRACE(reject_hrr);
5740
5741 ASSERT_TRUE(CreateClientAndServer());
5742 if (reject_hrr) {
5743 // Configure the server to prefer P-256, which will reject 0-RTT via
5744 // HelloRetryRequest.
5745 int p256 = NID_X9_62_prime256v1;
5746 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
5747 } else {
5748 // Disable 0-RTT on the server, so it will reject it.
5749 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04005750 }
David Benjamind6343572019-08-15 17:29:02 -04005751 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04005752
David Benjamind6343572019-08-15 17:29:02 -04005753 // The client handshake should return immediately into the early data state.
5754 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5755 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5756 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005757 EXPECT_TRUE(
5758 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005759
5760 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04005761 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04005762 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5763 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5764 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005765 EXPECT_FALSE(
5766 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005767
5768 // The client consumes the server response and signals 0-RTT rejection.
5769 for (;;) {
5770 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5771 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5772 int err = SSL_get_error(client_.get(), -1);
5773 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5774 break;
5775 }
5776 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04005777 }
5778
David Benjamind6343572019-08-15 17:29:02 -04005779 // As in TLS over TCP, 0-RTT rejection is sticky.
5780 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5781 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5782
5783 // Finish up the client and server handshakes.
5784 SSL_reset_early_data_reject(client_.get());
5785 ASSERT_TRUE(CompleteHandshakesForQUIC());
5786
5787 // Both sides can now exchange 1-RTT data.
5788 ExpectHandshakeSuccess();
5789 EXPECT_TRUE(SSL_session_reused(client_.get()));
5790 EXPECT_TRUE(SSL_session_reused(server_.get()));
5791 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5792 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5793 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5794 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04005795 }
David Benjaminfd863b62019-07-25 13:51:32 -04005796}
5797
David Benjaminee0716f2019-11-19 14:16:28 +08005798TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05005799 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08005800
5801 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5802 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5803 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
5804 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5805 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5806 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5807
5808 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5809 ASSERT_TRUE(session);
5810
5811 ASSERT_TRUE(CreateClientAndServer());
5812 SSL_set_session(client_.get(), session.get());
5813
5814 // Configure the certificate (re)verification to never complete. The client
5815 // handshake should pause.
5816 SSL_set_custom_verify(
5817 client_.get(), SSL_VERIFY_PEER,
5818 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5819 return ssl_verify_retry;
5820 });
5821 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5822 ASSERT_EQ(SSL_get_error(client_.get(), -1),
5823 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
5824
5825 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05005826 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005827
5828 // After the verification completes, the handshake progresses to the 0-RTT
5829 // point and releases keys.
5830 SSL_set_custom_verify(
5831 client_.get(), SSL_VERIFY_PEER,
5832 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5833 return ssl_verify_ok;
5834 });
5835 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5836 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005837 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005838}
5839
Steven Valdezc8e0f902018-07-14 11:23:01 -04005840// Test only releasing data to QUIC one byte at a time on request, to maximize
5841// state machine pauses. Additionally, test that existing asynchronous callbacks
5842// still work.
5843TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05005844 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005845
5846 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5847 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5848 ASSERT_TRUE(CreateClientAndServer());
5849
5850 // Install an asynchronous certificate callback.
5851 bool cert_cb_ok = false;
5852 SSL_set_cert_cb(server_.get(),
5853 [](SSL *, void *arg) -> int {
5854 return *static_cast<bool *>(arg) ? 1 : -1;
5855 },
5856 &cert_cb_ok);
5857
5858 for (;;) {
5859 int client_ret = SSL_do_handshake(client_.get());
5860 if (client_ret != 1) {
5861 ASSERT_EQ(client_ret, -1);
5862 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5863 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5864 }
5865
5866 int server_ret = SSL_do_handshake(server_.get());
5867 if (server_ret != 1) {
5868 ASSERT_EQ(server_ret, -1);
5869 int ssl_err = SSL_get_error(server_.get(), server_ret);
5870 switch (ssl_err) {
5871 case SSL_ERROR_WANT_READ:
5872 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5873 break;
5874 case SSL_ERROR_WANT_X509_LOOKUP:
5875 ASSERT_FALSE(cert_cb_ok);
5876 cert_cb_ok = true;
5877 break;
5878 default:
5879 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5880 }
5881 }
5882
5883 if (client_ret == 1 && server_ret == 1) {
5884 break;
5885 }
5886 }
5887
David Benjamind6343572019-08-15 17:29:02 -04005888 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005889}
5890
5891// Test buffering write data until explicit flushes.
5892TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04005893 AllowOutOfOrderWrites();
5894
Steven Valdezc8e0f902018-07-14 11:23:01 -04005895 struct BufferedFlight {
5896 std::vector<uint8_t> data[kNumQUICLevels];
5897 };
5898 static UnownedSSLExData<BufferedFlight> buffered_flights;
5899
David Benjamincc9d9352018-10-30 19:45:22 -05005900 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5901 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005902 BufferedFlight *flight = buffered_flights.Get(ssl);
5903 flight->data[level].insert(flight->data[level].end(), data, data + len);
5904 return 1;
5905 };
5906
5907 auto flush_flight = [](SSL *ssl) -> int {
5908 BufferedFlight *flight = buffered_flights.Get(ssl);
5909 for (size_t level = 0; level < kNumQUICLevels; level++) {
5910 if (!flight->data[level].empty()) {
5911 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5912 static_cast<ssl_encryption_level_t>(level),
5913 flight->data[level])) {
5914 return 0;
5915 }
5916 flight->data[level].clear();
5917 }
5918 }
5919 return 1;
5920 };
5921
David Benjamin1e859052020-02-09 16:04:58 -05005922 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5923 quic_method.add_handshake_data = add_handshake_data;
5924 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005925
5926 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5927 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5928 ASSERT_TRUE(CreateClientAndServer());
5929
5930 BufferedFlight client_flight, server_flight;
5931 buffered_flights.Set(client_.get(), &client_flight);
5932 buffered_flights.Set(server_.get(), &server_flight);
5933
David Benjamind6343572019-08-15 17:29:02 -04005934 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005935
David Benjamind6343572019-08-15 17:29:02 -04005936 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005937}
5938
5939// Test that excess data at one level is rejected. That is, if a single
5940// |SSL_provide_quic_data| call included both ServerHello and
5941// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5942// key change.
5943TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04005944 AllowOutOfOrderWrites();
5945
David Benjamincc9d9352018-10-30 19:45:22 -05005946 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5947 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005948 // Switch everything to the initial level.
5949 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5950 MakeConstSpan(data, len));
5951 };
5952
David Benjamin1e859052020-02-09 16:04:58 -05005953 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5954 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005955
5956 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5957 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5958 ASSERT_TRUE(CreateClientAndServer());
5959
5960 // Send the ClientHello and ServerHello through Finished.
5961 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5962 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5963 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5964 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5965 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5966
5967 // The client is still waiting for the ServerHello at initial
5968 // encryption.
5969 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5970
David Benjamincc9d9352018-10-30 19:45:22 -05005971 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5972 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005973 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5974
5975 // The client reads ServerHello successfully, but then rejects the buffered
5976 // EncryptedExtensions on key change.
5977 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5978 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5979 uint32_t err = ERR_get_error();
5980 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05005981 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005982
David Benjamin1e859052020-02-09 16:04:58 -05005983 // The client sends an alert in response to this. The alert is sent at
5984 // handshake level because we install write secrets before read secrets and
5985 // the error is discovered when installing the read secret. (How to send
5986 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04005987 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05005988 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04005989 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005990
David Benjamin5298ef92020-03-13 12:17:30 -04005991 // Sanity-check handshake secrets. The error is discovered while setting the
5992 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05005993 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04005994 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005995}
5996
5997// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5998TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05005999 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006000
6001 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6002 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6003 ASSERT_TRUE(CreateClientAndServer());
6004
6005 // Send the ClientHello and ServerHello through Finished.
6006 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6007 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6008 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6009 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6010 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6011
6012 // The client is still waiting for the ServerHello at initial
6013 // encryption.
6014 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6015
6016 // Data cannot be provided at the next level.
6017 std::vector<uint8_t> data;
6018 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006019 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006020 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6021 data.data(), data.size()));
6022 ERR_clear_error();
6023
6024 // Progress to EncryptedExtensions.
6025 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6026 data.data(), data.size()));
6027 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6028 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6029 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6030
6031 // Data cannot be provided at the previous level.
6032 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006033 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006034 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6035 data.data(), data.size()));
6036}
6037
6038TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006039 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006040
6041 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6042 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6043 ASSERT_TRUE(CreateClientAndServer());
6044
6045 size_t limit =
6046 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6047 uint8_t b = 0;
6048 for (size_t i = 0; i < limit; i++) {
6049 ASSERT_TRUE(
6050 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6051 }
6052
6053 EXPECT_FALSE(
6054 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6055}
6056
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006057// Provide invalid post-handshake data.
6058TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006059 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006060
6061 g_last_session = nullptr;
6062
6063 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6064 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6065 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6066 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6067 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006068 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006069
6070 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6071 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006072 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6073 EXPECT_FALSE(transport_->client()->has_alert());
6074 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006075
6076 // Junk sent as part of post-handshake data should cause an error.
6077 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6078 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6079 kJunk, sizeof(kJunk)));
6080 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6081}
6082
Nick Harper80ddfc72020-03-11 18:26:31 -07006083static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6084 Span<const uint8_t> expected) {
6085 const uint8_t *received;
6086 size_t received_len;
6087 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6088 ASSERT_EQ(received_len, expected.size());
6089 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6090}
6091
6092TEST_F(QUICMethodTest, SetTransportParameters) {
6093 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6094 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6095 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6096
6097 ASSERT_TRUE(CreateClientAndServer());
6098 uint8_t kClientParams[] = {1, 2, 3, 4};
6099 uint8_t kServerParams[] = {5, 6, 7};
6100 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6101 sizeof(kClientParams)));
6102 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6103 sizeof(kServerParams)));
6104
6105 ASSERT_TRUE(CompleteHandshakesForQUIC());
6106 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6107 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6108}
6109
6110TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6111 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6112 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6113 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6114
6115 ASSERT_TRUE(CreateClientAndServer());
6116 uint8_t kClientParams[] = {1, 2, 3, 4};
6117 static uint8_t kServerParams[] = {5, 6, 7};
6118 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6119 sizeof(kClientParams)));
6120 SSL_CTX_set_tlsext_servername_callback(
6121 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6122 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6123 sizeof(kServerParams)));
6124 return SSL_TLSEXT_ERR_OK;
6125 });
6126
6127 ASSERT_TRUE(CompleteHandshakesForQUIC());
6128 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6129 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6130}
6131
Nick Harper6bfd25c2020-03-30 17:15:19 -07006132TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6133 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6134
6135 g_last_session = nullptr;
6136
6137 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6138 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6139 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6140 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6141
6142 ASSERT_TRUE(CreateClientAndServer());
6143 ASSERT_TRUE(CompleteHandshakesForQUIC());
6144
6145 ExpectHandshakeSuccess();
6146 EXPECT_FALSE(SSL_session_reused(client_.get()));
6147 EXPECT_FALSE(SSL_session_reused(server_.get()));
6148
6149 // The server sent NewSessionTicket messages in the handshake.
6150 EXPECT_FALSE(g_last_session);
6151 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6152 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6153 EXPECT_TRUE(g_last_session);
6154
6155 // Pretend that g_last_session came from a TLS-over-TCP connection.
6156 g_last_session.get()->is_quic = false;
6157
6158 // Create a second connection and verify that resumption does not occur with
6159 // a session from a non-QUIC connection. This tests that the client does not
6160 // offer over QUIC a session believed to be received over TCP. The server
6161 // believes this is a QUIC session, so if the client offered the session, the
6162 // server would have resumed it.
6163 ASSERT_TRUE(CreateClientAndServer());
6164 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6165 SSL_set_session(client_.get(), session.get());
6166
6167 ASSERT_TRUE(CompleteHandshakesForQUIC());
6168 ExpectHandshakeSuccess();
6169 EXPECT_FALSE(SSL_session_reused(client_.get()));
6170 EXPECT_FALSE(SSL_session_reused(server_.get()));
6171}
6172
6173TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6174 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6175
6176 g_last_session = nullptr;
6177
6178 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6179 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6180 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6181 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6182
6183 ASSERT_TRUE(CreateClientAndServer());
6184 ASSERT_TRUE(CompleteHandshakesForQUIC());
6185
6186 ExpectHandshakeSuccess();
6187 EXPECT_FALSE(SSL_session_reused(client_.get()));
6188 EXPECT_FALSE(SSL_session_reused(server_.get()));
6189
6190 // The server sent NewSessionTicket messages in the handshake.
6191 EXPECT_FALSE(g_last_session);
6192 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6193 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6194 EXPECT_TRUE(g_last_session);
6195
6196 // Attempt a resumption with g_last_session using TLS_method.
6197 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6198 ASSERT_TRUE(client_ctx);
6199
6200 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6201
6202 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6203 server(SSL_new(server_ctx_.get()));
6204 ASSERT_TRUE(client);
6205 ASSERT_TRUE(server);
6206 SSL_set_connect_state(client.get());
6207 SSL_set_accept_state(server.get());
6208
6209 // The TLS-over-TCP client will refuse to resume with a quic session, so
6210 // mark is_quic = false to bypass the client check to test the server check.
6211 g_last_session.get()->is_quic = false;
6212 SSL_set_session(client.get(), g_last_session.get());
6213
6214 BIO *bio1, *bio2;
6215 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6216
6217 // SSL_set_bio takes ownership.
6218 SSL_set_bio(client.get(), bio1, bio1);
6219 SSL_set_bio(server.get(), bio2, bio2);
6220 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6221
6222 EXPECT_FALSE(SSL_session_reused(client.get()));
6223 EXPECT_FALSE(SSL_session_reused(server.get()));
6224}
6225
Nick Harper72cff812020-03-26 18:06:16 -07006226TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6227 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6228 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6229 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6230
6231 ASSERT_TRUE(CreateClientAndServer());
6232 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6233 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6234}
6235
6236TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6237 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6238 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6239 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6240
6241 ASSERT_TRUE(CreateClientAndServer());
6242 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6243 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6244}
6245
David Schinazi3d8b8c32021-01-14 11:25:49 -08006246TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6247 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6248 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6249 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6250
6251 ASSERT_TRUE(CreateClientAndServer());
6252 uint8_t kClientParams[] = {1, 2, 3, 4};
6253 uint8_t kServerParams[] = {5, 6, 7};
6254 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6255 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6256 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6257 sizeof(kClientParams)));
6258 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6259 sizeof(kServerParams)));
6260
6261 ASSERT_TRUE(CompleteHandshakesForQUIC());
6262 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6263 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6264}
6265
6266TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6267 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6268 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6269 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6270
6271 ASSERT_TRUE(CreateClientAndServer());
6272 uint8_t kClientParams[] = {1, 2, 3, 4};
6273 uint8_t kServerParams[] = {5, 6, 7};
6274 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6275 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6276 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6277 sizeof(kClientParams)));
6278 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6279 sizeof(kServerParams)));
6280
6281 ASSERT_TRUE(CompleteHandshakesForQUIC());
6282 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6283 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6284}
6285
6286TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6287 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6288 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6289 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6290
6291 ASSERT_TRUE(CreateClientAndServer());
6292 uint8_t kClientParams[] = {1, 2, 3, 4};
6293 uint8_t kServerParams[] = {5, 6, 7};
6294 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6295 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6296 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6297 sizeof(kClientParams)));
6298 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6299 sizeof(kServerParams)));
6300
6301 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6302}
6303
6304TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6305 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6306 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6307 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6308
6309 ASSERT_TRUE(CreateClientAndServer());
6310 uint8_t kClientParams[] = {1, 2, 3, 4};
6311 uint8_t kServerParams[] = {5, 6, 7};
6312 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6313 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6314 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6315 sizeof(kClientParams)));
6316 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6317 sizeof(kServerParams)));
6318
6319 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6320}
6321
David Benjaminc47bfce2021-01-20 17:10:32 -05006322// Test that the default QUIC code point is consistent with
6323// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6324// update the two values together.
6325TEST_F(QUICMethodTest, QuicCodePointDefault) {
6326 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6327 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6328 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6329 SSL_CTX_set_select_certificate_cb(
6330 server_ctx_.get(),
6331 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6332 const uint8_t *data;
6333 size_t len;
6334 if (!SSL_early_callback_ctx_extension_get(
6335 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6336 &len)) {
6337 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6338 return ssl_select_cert_error;
6339 }
6340 return ssl_select_cert_success;
6341 });
6342
6343 ASSERT_TRUE(CreateClientAndServer());
6344 ASSERT_TRUE(CompleteHandshakesForQUIC());
6345}
6346
Adam Langley7540cc22019-04-18 09:56:13 -07006347extern "C" {
6348int BORINGSSL_enum_c_type_test(void);
6349}
6350
6351TEST(SSLTest, EnumTypes) {
6352 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6353 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6354}
6355
David Benjaminb29e1e12019-05-06 14:44:46 -05006356TEST_P(SSLVersionTest, DoubleSSLError) {
6357 // Connect the inner SSL connections.
6358 ASSERT_TRUE(Connect());
6359
6360 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6361 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6362 ASSERT_TRUE(bio_method);
6363 ASSERT_TRUE(BIO_meth_set_read(
6364 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6365 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6366 int ret = SSL_read(ssl, out, len);
6367 int ssl_ret = SSL_get_error(ssl, ret);
6368 if (ssl_ret == SSL_ERROR_WANT_READ) {
6369 BIO_set_retry_read(bio);
6370 }
6371 return ret;
6372 }));
6373 ASSERT_TRUE(BIO_meth_set_write(
6374 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6375 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6376 int ret = SSL_write(ssl, in, len);
6377 int ssl_ret = SSL_get_error(ssl, ret);
6378 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6379 BIO_set_retry_write(bio);
6380 }
6381 return ret;
6382 }));
6383 ASSERT_TRUE(BIO_meth_set_ctrl(
6384 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6385 // |SSL| objects require |BIO_flush| support.
6386 if (cmd == BIO_CTRL_FLUSH) {
6387 return 1;
6388 }
6389 return 0;
6390 }));
6391
6392 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6393 ASSERT_TRUE(client_bio);
6394 BIO_set_data(client_bio.get(), client_.get());
6395 BIO_set_init(client_bio.get(), 1);
6396
6397 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6398 ASSERT_TRUE(server_bio);
6399 BIO_set_data(server_bio.get(), server_.get());
6400 BIO_set_init(server_bio.get(), 1);
6401
6402 // Wrap the inner connections in another layer of SSL.
6403 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6404 ASSERT_TRUE(client_outer);
6405 SSL_set_connect_state(client_outer.get());
6406 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6407 client_bio.release(); // |SSL_set_bio| takes ownership.
6408
6409 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6410 ASSERT_TRUE(server_outer);
6411 SSL_set_accept_state(server_outer.get());
6412 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6413 server_bio.release(); // |SSL_set_bio| takes ownership.
6414
6415 // Configure |client_outer| to reject the server certificate.
6416 SSL_set_custom_verify(
6417 client_outer.get(), SSL_VERIFY_PEER,
6418 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6419 return ssl_verify_invalid;
6420 });
6421
6422 for (;;) {
6423 int client_ret = SSL_do_handshake(client_outer.get());
6424 int client_err = SSL_get_error(client_outer.get(), client_ret);
6425 if (client_err != SSL_ERROR_WANT_READ &&
6426 client_err != SSL_ERROR_WANT_WRITE) {
6427 // The client handshake should terminate on a certificate verification
6428 // error.
6429 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6430 uint32_t err = ERR_peek_error();
6431 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6432 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6433 break;
6434 }
6435
6436 // Run the server handshake and continue.
6437 int server_ret = SSL_do_handshake(server_outer.get());
6438 int server_err = SSL_get_error(server_outer.get(), server_ret);
6439 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6440 server_err == SSL_ERROR_WANT_READ ||
6441 server_err == SSL_ERROR_WANT_WRITE);
6442 }
6443}
6444
David Benjamin1b819472020-06-09 14:01:02 -04006445TEST_P(SSLVersionTest, SameKeyResume) {
6446 uint8_t key[48];
6447 RAND_bytes(key, sizeof(key));
6448
6449 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6450 ASSERT_TRUE(server_ctx2);
6451 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6452 ASSERT_TRUE(
6453 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6454 ASSERT_TRUE(
6455 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6456
6457 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6458 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6459 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6460
6461 // Establish a session for |server_ctx_|.
6462 bssl::UniquePtr<SSL_SESSION> session =
6463 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6464 ASSERT_TRUE(session);
6465 ClientConfig config;
6466 config.session = session.get();
6467
6468 // Resuming with |server_ctx_| again works.
6469 bssl::UniquePtr<SSL> client, server;
6470 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6471 server_ctx_.get(), config));
6472 EXPECT_TRUE(SSL_session_reused(client.get()));
6473 EXPECT_TRUE(SSL_session_reused(server.get()));
6474
6475 // Resuming with |server_ctx2| also works.
6476 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6477 server_ctx2.get(), config));
6478 EXPECT_TRUE(SSL_session_reused(client.get()));
6479 EXPECT_TRUE(SSL_session_reused(server.get()));
6480}
6481
6482TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6483 uint8_t key1[48], key2[48];
6484 RAND_bytes(key1, sizeof(key1));
6485 RAND_bytes(key2, sizeof(key2));
6486
6487 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6488 ASSERT_TRUE(server_ctx2);
6489 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6490 ASSERT_TRUE(
6491 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
6492 ASSERT_TRUE(
6493 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
6494
6495 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6496 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6497 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6498
6499 // Establish a session for |server_ctx_|.
6500 bssl::UniquePtr<SSL_SESSION> session =
6501 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6502 ASSERT_TRUE(session);
6503 ClientConfig config;
6504 config.session = session.get();
6505
6506 // Resuming with |server_ctx_| again works.
6507 bssl::UniquePtr<SSL> client, server;
6508 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6509 server_ctx_.get(), config));
6510 EXPECT_TRUE(SSL_session_reused(client.get()));
6511 EXPECT_TRUE(SSL_session_reused(server.get()));
6512
6513 // Resuming with |server_ctx2| does not work.
6514 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6515 server_ctx2.get(), config));
6516 EXPECT_FALSE(SSL_session_reused(client.get()));
6517 EXPECT_FALSE(SSL_session_reused(server.get()));
6518}
6519
6520TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
6521 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6522 ASSERT_TRUE(server_ctx2);
6523 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6524
6525 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6526 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6527 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6528
6529 // Establish a session for |server_ctx_|.
6530 bssl::UniquePtr<SSL_SESSION> session =
6531 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6532 ASSERT_TRUE(session);
6533 ClientConfig config;
6534 config.session = session.get();
6535
6536 // Resuming with |server_ctx_| again works.
6537 bssl::UniquePtr<SSL> client, server;
6538 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6539 server_ctx_.get(), config));
6540 EXPECT_TRUE(SSL_session_reused(client.get()));
6541 EXPECT_TRUE(SSL_session_reused(server.get()));
6542
6543 // Resuming with |server_ctx2| does not work.
6544 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6545 server_ctx2.get(), config));
6546 EXPECT_FALSE(SSL_session_reused(client.get()));
6547 EXPECT_FALSE(SSL_session_reused(server.get()));
6548}
6549
Adam Langley47cefed2021-05-26 13:36:40 -07006550Span<const uint8_t> SessionIDOf(const SSL* ssl) {
6551 const SSL_SESSION *session = SSL_get_session(ssl);
6552 unsigned len;
6553 const uint8_t *data = SSL_SESSION_get_id(session, &len);
6554 return MakeConstSpan(data, len);
6555}
6556
6557TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
6558 // This checks that the session IDs at client and server match after a ticket
6559 // resumption. It's unclear whether this should be true, but Envoy depends
6560 // on it in their tests so this will give an early signal if we break it.
6561 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6562 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6563
6564 bssl::UniquePtr<SSL_SESSION> session =
6565 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6566
6567 bssl::UniquePtr<SSL> client, server;
6568 ClientConfig config;
6569 config.session = session.get();
6570 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6571 server_ctx_.get(), config));
6572 EXPECT_TRUE(SSL_session_reused(client.get()));
6573 EXPECT_TRUE(SSL_session_reused(server.get()));
6574
6575 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
6576}
6577
David Benjamin0e7dbd52019-05-15 16:01:18 -04006578TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04006579 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006580 ASSERT_TRUE(ctx);
6581
David Benjamin0e7dbd52019-05-15 16:01:18 -04006582 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
6583 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
6584 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6585 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
6586
6587 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006588 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006589 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04006590 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006591
6592 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
6593
6594 // Write "hello" until the buffer is full, so |client| has a pending write.
6595 size_t num_writes = 0;
6596 for (;;) {
6597 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
6598 if (ret != int(sizeof(kInput))) {
6599 ASSERT_EQ(-1, ret);
6600 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
6601 break;
6602 }
6603 num_writes++;
6604 }
6605
6606 // Encrypt a HelloRequest.
6607 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
6608#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
6609 // Fuzzer-mode records are unencrypted.
6610 uint8_t record[5 + sizeof(in)];
6611 record[0] = SSL3_RT_HANDSHAKE;
6612 record[1] = 3;
6613 record[2] = 3; // TLS 1.2
6614 record[3] = 0;
6615 record[4] = sizeof(record) - 5;
6616 memcpy(record + 5, in, sizeof(in));
6617#else
6618 // Extract key material from |server|.
6619 static const size_t kKeyLen = 32;
6620 static const size_t kNonceLen = 12;
6621 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
6622 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
6623 ASSERT_TRUE(
6624 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
6625 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
6626 Span<uint8_t> nonce =
6627 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
6628
6629 uint8_t ad[13];
6630 uint64_t seq = SSL_get_write_sequence(server.get());
6631 for (size_t i = 0; i < 8; i++) {
6632 // The nonce is XORed with the sequence number.
6633 nonce[11 - i] ^= uint8_t(seq);
6634 ad[7 - i] = uint8_t(seq);
6635 seq >>= 8;
6636 }
6637
6638 ad[8] = SSL3_RT_HANDSHAKE;
6639 ad[9] = 3;
6640 ad[10] = 3; // TLS 1.2
6641 ad[11] = 0;
6642 ad[12] = sizeof(in);
6643
6644 uint8_t record[5 + sizeof(in) + 16];
6645 record[0] = SSL3_RT_HANDSHAKE;
6646 record[1] = 3;
6647 record[2] = 3; // TLS 1.2
6648 record[3] = 0;
6649 record[4] = sizeof(record) - 5;
6650
6651 ScopedEVP_AEAD_CTX aead;
6652 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
6653 key.data(), key.size(),
6654 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
6655 size_t len;
6656 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
6657 sizeof(record) - 5, nonce.data(), nonce.size(),
6658 in, sizeof(in), ad, sizeof(ad)));
6659 ASSERT_EQ(sizeof(record) - 5, len);
6660#endif // BORINGSSL_UNSAFE_FUZZER_MODE
6661
6662 ASSERT_EQ(int(sizeof(record)),
6663 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
6664
6665 // |SSL_read| should pick up the HelloRequest.
6666 uint8_t byte;
6667 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6668 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6669
6670 // Drain the data from the |client|.
6671 uint8_t buf[sizeof(kInput)];
6672 for (size_t i = 0; i < num_writes; i++) {
6673 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6674 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6675 }
6676
6677 // |client| should be able to finish the pending write and continue to write,
6678 // despite the paused HelloRequest.
6679 ASSERT_EQ(int(sizeof(kInput)),
6680 SSL_write(client.get(), kInput, sizeof(kInput)));
6681 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6682 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6683
6684 ASSERT_EQ(int(sizeof(kInput)),
6685 SSL_write(client.get(), kInput, sizeof(kInput)));
6686 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6687 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6688
6689 // |SSL_read| is stuck until we acknowledge the HelloRequest.
6690 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6691 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6692
6693 ASSERT_TRUE(SSL_renegotiate(client.get()));
6694 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6695 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
6696
6697 // We never renegotiate as a server.
6698 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
6699 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
6700 uint32_t err = ERR_get_error();
6701 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6702 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
6703}
6704
David Benjaminf9e0cda2020-03-23 18:29:09 -04006705
6706TEST(SSLTest, CopyWithoutEarlyData) {
6707 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006708 bssl::UniquePtr<SSL_CTX> server_ctx(
6709 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04006710 ASSERT_TRUE(client_ctx);
6711 ASSERT_TRUE(server_ctx);
6712
David Benjaminf9e0cda2020-03-23 18:29:09 -04006713 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
6714 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
6715 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
6716 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
6717
6718 bssl::UniquePtr<SSL_SESSION> session =
6719 CreateClientSession(client_ctx.get(), server_ctx.get());
6720 ASSERT_TRUE(session);
6721
6722 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04006723 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006724 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
6725 server_ctx.get()));
6726 SSL_set_session(client.get(), session.get());
6727 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04006728 ASSERT_EQ(1, SSL_do_handshake(client.get()));
6729 EXPECT_TRUE(SSL_in_early_data(client.get()));
6730
6731 // |SSL_SESSION_copy_without_early_data| should disable early data but
6732 // still resume the session.
6733 bssl::UniquePtr<SSL_SESSION> session2(
6734 SSL_SESSION_copy_without_early_data(session.get()));
6735 ASSERT_TRUE(session2);
6736 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04006737 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
6738 server_ctx.get()));
6739 SSL_set_session(client.get(), session2.get());
6740 SSL_set_early_data_enabled(client.get(), 1);
6741 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04006742 EXPECT_TRUE(SSL_session_reused(client.get()));
6743 EXPECT_EQ(ssl_early_data_unsupported_for_session,
6744 SSL_get_early_data_reason(client.get()));
6745
6746 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
6747 // when passed an early-data-incapable session.
6748 bssl::UniquePtr<SSL_SESSION> session3(
6749 SSL_SESSION_copy_without_early_data(session2.get()));
6750 EXPECT_EQ(session2.get(), session3.get());
6751}
6752
Adam Langley53a17f52020-05-26 14:44:07 -07006753TEST(SSLTest, ProcessTLS13NewSessionTicket) {
6754 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07006755 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006756 bssl::UniquePtr<SSL_CTX> server_ctx(
6757 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07006758 ASSERT_TRUE(client_ctx);
6759 ASSERT_TRUE(server_ctx);
6760 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
6761 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
6762 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
6763 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07006764
6765 bssl::UniquePtr<SSL> client, server;
6766 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6767 server_ctx.get()));
6768 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
6769
6770 // Process a TLS 1.3 NewSessionTicket.
6771 static const uint8_t kTicket[] = {
6772 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
6773 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
6774 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
6775 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
6776 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
6777 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
6778 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
6779 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
6780 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
6781 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
6782 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
6783 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
6784 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
6785 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
6786 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
6787 0x00, 0x00,
6788 };
6789 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
6790 client.get(), kTicket, sizeof(kTicket)));
6791 ASSERT_TRUE(session);
6792 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
6793
6794 uint8_t *session_buf = nullptr;
6795 size_t session_length = 0;
6796 ASSERT_TRUE(
6797 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
6798 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
6799 ASSERT_TRUE(session_buf);
6800 ASSERT_GT(session_length, 0u);
6801
6802 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
6803 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
6804 sizeof(kTicket)));
6805
6806 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
6807 // handshake completes.
6808 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
6809 ASSERT_TRUE(client2);
6810 SSL_set_connect_state(client2.get());
6811 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
6812 sizeof(kTicket)));
6813}
6814
David Benjamin3989c992020-10-09 14:12:06 -04006815TEST(SSLTest, BIO) {
6816 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006817 bssl::UniquePtr<SSL_CTX> server_ctx(
6818 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04006819 ASSERT_TRUE(client_ctx);
6820 ASSERT_TRUE(server_ctx);
6821
David Benjamin3989c992020-10-09 14:12:06 -04006822 for (bool take_ownership : {true, false}) {
6823 // For simplicity, get the handshake out of the way first.
6824 bssl::UniquePtr<SSL> client, server;
6825 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6826 server_ctx.get()));
6827
6828 // Wrap |client| in an SSL BIO.
6829 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
6830 ASSERT_TRUE(client_bio);
6831 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
6832 if (take_ownership) {
6833 client.release();
6834 }
6835
6836 // Flushing the BIO should not crash.
6837 EXPECT_EQ(1, BIO_flush(client_bio.get()));
6838
6839 // Exchange some data.
6840 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
6841 uint8_t buf[5];
6842 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
6843 EXPECT_EQ(Bytes("hello"), Bytes(buf));
6844
6845 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
6846 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
6847 EXPECT_EQ(Bytes("world"), Bytes(buf));
6848
6849 // |BIO_should_read| should work.
6850 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
6851 EXPECT_TRUE(BIO_should_read(client_bio.get()));
6852
6853 // Writing data should eventually exceed the buffer size and fail, reporting
6854 // |BIO_should_write|.
6855 int ret;
6856 for (int i = 0; i < 1024; i++) {
6857 std::vector<uint8_t> buffer(1024);
6858 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
6859 if (ret <= 0) {
6860 break;
6861 }
6862 }
6863 EXPECT_EQ(-1, ret);
6864 EXPECT_TRUE(BIO_should_write(client_bio.get()));
6865 }
6866}
6867
David Benjamin12a3e7e2021-04-13 11:47:36 -04006868TEST(SSLTest, ALPNConfig) {
6869 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6870 ASSERT_TRUE(ctx);
6871 bssl::UniquePtr<X509> cert = GetTestCertificate();
6872 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
6873 ASSERT_TRUE(cert);
6874 ASSERT_TRUE(key);
6875 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
6876 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
6877
6878 // Set up some machinery to check the configured ALPN against what is actually
6879 // sent over the wire. Note that the ALPN callback is only called when the
6880 // client offers ALPN.
6881 std::vector<uint8_t> observed_alpn;
6882 SSL_CTX_set_alpn_select_cb(
6883 ctx.get(),
6884 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6885 unsigned in_len, void *arg) -> int {
6886 std::vector<uint8_t> *observed_alpn_ptr =
6887 static_cast<std::vector<uint8_t> *>(arg);
6888 observed_alpn_ptr->assign(in, in + in_len);
6889 return SSL_TLSEXT_ERR_NOACK;
6890 },
6891 &observed_alpn);
6892 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
6893 observed_alpn.clear();
6894 bssl::UniquePtr<SSL> client, server;
6895 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
6896 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
6897 };
6898
6899 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
6900 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
6901 0x03, 'b', 'a', 'r'};
6902 EXPECT_EQ(0,
6903 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
6904 check_alpn_proto(kValidList);
6905
6906 // Invalid lists are rejected.
6907 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
6908 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
6909 sizeof(kInvalidList)));
6910
6911 // Empty lists are valid and are interpreted as disabling ALPN.
6912 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
6913 check_alpn_proto({});
6914}
6915
David Benjamin2f3958a2021-04-16 11:55:23 -04006916// Test that the key usage checker can correctly handle issuerUID and
6917// subjectUID. See https://crbug.com/1199744.
6918TEST(SSLTest, KeyUsageWithUIDs) {
6919 static const char kGoodKeyUsage[] = R"(
6920-----BEGIN CERTIFICATE-----
6921MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
6922AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
6923aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
6924CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
6925ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
69264r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
6927Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
6928ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
6929A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
693034EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
69314Z7qDhjIhiF4dM0uEDYRVA==
6932-----END CERTIFICATE-----
6933)";
6934 static const char kBadKeyUsage[] = R"(
6935-----BEGIN CERTIFICATE-----
6936MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
6937AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
6938aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
6939CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
6940ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
69414r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
6942Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
6943ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
6944A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
6945taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
6946RHrQbWsFUakETXL9QMlegh5t
6947-----END CERTIFICATE-----
6948)";
6949
6950 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
6951 ASSERT_TRUE(good);
6952 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
6953 ASSERT_TRUE(bad);
6954
6955 // We check key usage when configuring EC certificates to distinguish ECDSA
6956 // and ECDH.
6957 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6958 ASSERT_TRUE(ctx);
6959 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
6960 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
6961}
6962
David Benjamin9b2cdb72021-04-01 23:21:53 -04006963// Test that |SSL_can_release_private_key| reports true as early as expected.
6964// The internal asserts in the library check we do not report true too early.
6965TEST(SSLTest, CanReleasePrivateKey) {
6966 bssl::UniquePtr<SSL_CTX> client_ctx =
6967 CreateContextWithTestCertificate(TLS_method());
6968 ASSERT_TRUE(client_ctx);
6969 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
6970
6971 // Note this assumes the transport buffer is large enough to fit the client
6972 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
6973 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
6974 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
6975 // Write the ClientHello.
6976 ASSERT_EQ(-1, SSL_do_handshake(client));
6977 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
6978
6979 // Consume the ClientHello and write the server flight.
6980 ASSERT_EQ(-1, SSL_do_handshake(server));
6981 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
6982
6983 EXPECT_TRUE(SSL_can_release_private_key(server));
6984 };
6985
6986 {
6987 SCOPED_TRACE("TLS 1.2 ECDHE");
6988 bssl::UniquePtr<SSL_CTX> server_ctx(
6989 CreateContextWithTestCertificate(TLS_method()));
6990 ASSERT_TRUE(server_ctx);
6991 ASSERT_TRUE(
6992 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
6993 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6994 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
6995 // Configure the server to request client certificates, so we can also test
6996 // the client half.
6997 SSL_CTX_set_custom_verify(
6998 server_ctx.get(), SSL_VERIFY_PEER,
6999 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7000 bssl::UniquePtr<SSL> client, server;
7001 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7002 server_ctx.get()));
7003 check_first_server_round_trip(client.get(), server.get());
7004
7005 // Consume the server flight and write the client response. The client still
7006 // has a Finished message to consume but can also release its key early.
7007 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7008 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7009 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7010
7011 // However, a client that has not disabled renegotiation can never release
7012 // the key.
7013 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7014 server_ctx.get()));
7015 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7016 check_first_server_round_trip(client.get(), server.get());
7017 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7018 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7019 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7020 }
7021
7022 {
7023 SCOPED_TRACE("TLS 1.2 resumption");
7024 bssl::UniquePtr<SSL_CTX> server_ctx(
7025 CreateContextWithTestCertificate(TLS_method()));
7026 ASSERT_TRUE(server_ctx);
7027 ASSERT_TRUE(
7028 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7029 bssl::UniquePtr<SSL_SESSION> session =
7030 CreateClientSession(client_ctx.get(), server_ctx.get());
7031 ASSERT_TRUE(session);
7032 bssl::UniquePtr<SSL> client, server;
7033 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7034 server_ctx.get()));
7035 SSL_set_session(client.get(), session.get());
7036 check_first_server_round_trip(client.get(), server.get());
7037 }
7038
7039 {
7040 SCOPED_TRACE("TLS 1.3 1-RTT");
7041 bssl::UniquePtr<SSL_CTX> server_ctx(
7042 CreateContextWithTestCertificate(TLS_method()));
7043 ASSERT_TRUE(server_ctx);
7044 ASSERT_TRUE(
7045 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7046 bssl::UniquePtr<SSL> client, server;
7047 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7048 server_ctx.get()));
7049 check_first_server_round_trip(client.get(), server.get());
7050 }
7051
7052 {
7053 SCOPED_TRACE("TLS 1.3 resumption");
7054 bssl::UniquePtr<SSL_CTX> server_ctx(
7055 CreateContextWithTestCertificate(TLS_method()));
7056 ASSERT_TRUE(server_ctx);
7057 ASSERT_TRUE(
7058 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7059 bssl::UniquePtr<SSL_SESSION> session =
7060 CreateClientSession(client_ctx.get(), server_ctx.get());
7061 ASSERT_TRUE(session);
7062 bssl::UniquePtr<SSL> client, server;
7063 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7064 server_ctx.get()));
7065 SSL_set_session(client.get(), session.get());
7066 check_first_server_round_trip(client.get(), server.get());
7067 }
7068}
7069
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007070} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007071BSSL_NAMESPACE_END