blob: fe85840d557397c65f1874c45cc6c865922debd6 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
Steven Valdezc8e0f902018-07-14 11:23:01 -040020#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040021#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050022#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040023#include <vector>
24
David Benjamin96628432017-01-19 19:05:47 -050025#include <gtest/gtest.h>
26
David Benjamin0e7dbd52019-05-15 16:01:18 -040027#include <openssl/aead.h>
David Benjamin751e8892014-10-19 00:59:36 -040028#include <openssl/base64.h>
David Benjamine9c5d722021-06-09 17:43:16 -040029#include <openssl/bytestring.h>
David Benjamin751e8892014-10-19 00:59:36 -040030#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040032#include <openssl/crypto.h>
Daniel McArdle00e434d2021-02-18 11:47:18 -050033#include <openssl/curve25519.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/hmac.h>
David Benjaminc890ae52021-06-06 13:32:29 -040036#include <openssl/hpke.h>
David Benjaminde942382016-02-11 12:02:01 -050037#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040038#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040039#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040040#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050041#include <openssl/x509.h>
Adam Langley7e7e6b62021-12-06 13:04:07 -080042#include <openssl/x509v3.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040043
Steven Valdez87eab492016-06-27 16:34:59 -040044#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040045#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020046#include "../crypto/test/test_util.h"
47
David Benjamin721e8b72016-08-03 13:13:17 -040048#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040049// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040050OPENSSL_MSVC_PRAGMA(warning(push, 3))
51#include <winsock2.h>
52OPENSSL_MSVC_PRAGMA(warning(pop))
53#else
54#include <sys/time.h>
55#endif
56
David Benjamin5b33eff2018-09-22 16:52:48 -070057#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040058#include <thread>
59#endif
60
David Benjamin1d77e562015-03-22 17:22:08 -040061
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070062BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070063
64namespace {
65
Martin Kreichgauer1a663262017-08-16 14:54:04 -070066#define TRACED_CALL(code) \
67 do { \
68 SCOPED_TRACE("<- called from here"); \
69 code; \
70 if (::testing::Test::HasFatalFailure()) { \
71 return; \
72 } \
73 } while (false)
74
Martin Kreichgauer72912d22017-08-04 12:06:43 -070075struct VersionParam {
76 uint16_t version;
77 enum { is_tls, is_dtls } ssl_method;
78 const char name[8];
79};
80
81static const size_t kTicketKeyLen = 48;
82
83static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070084 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
85 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
86 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070087 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070088 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
89 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
90};
91
David Benjamin1d77e562015-03-22 17:22:08 -040092struct ExpectedCipher {
93 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040094 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040095};
David Benjaminbb0a17c2014-09-20 15:35:39 -040096
David Benjamin1d77e562015-03-22 17:22:08 -040097struct CipherTest {
98 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040099 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -0500100 // The list of expected ciphers, in order.
101 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800102 // True if this cipher list should fail in strict mode.
103 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400104};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400105
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100106struct CurveTest {
107 // The rule string to apply.
108 const char *rule;
109 // The list of expected curves, in order.
110 std::vector<uint16_t> expected;
111};
112
Steven Valdezc8e0f902018-07-14 11:23:01 -0400113template <typename T>
114class UnownedSSLExData {
115 public:
116 UnownedSSLExData() {
117 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
118 }
119
120 T *Get(const SSL *ssl) {
121 return index_ < 0 ? nullptr
122 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
123 }
124
125 bool Set(SSL *ssl, T *t) {
126 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
127 }
128
129 private:
130 int index_;
131};
132
David Benjaminfb974e62015-12-16 19:34:22 -0500133static const CipherTest kCipherTests[] = {
134 // Selecting individual ciphers should work.
135 {
136 "ECDHE-ECDSA-CHACHA20-POLY1305:"
137 "ECDHE-RSA-CHACHA20-POLY1305:"
138 "ECDHE-ECDSA-AES128-GCM-SHA256:"
139 "ECDHE-RSA-AES128-GCM-SHA256",
140 {
141 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500142 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500143 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
144 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
145 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800146 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500147 },
148 // + reorders selected ciphers to the end, keeping their relative order.
149 {
150 "ECDHE-ECDSA-CHACHA20-POLY1305:"
151 "ECDHE-RSA-CHACHA20-POLY1305:"
152 "ECDHE-ECDSA-AES128-GCM-SHA256:"
153 "ECDHE-RSA-AES128-GCM-SHA256:"
154 "+aRSA",
155 {
156 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500157 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
158 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500159 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
160 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800161 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500162 },
163 // ! banishes ciphers from future selections.
164 {
165 "!aRSA:"
166 "ECDHE-ECDSA-CHACHA20-POLY1305:"
167 "ECDHE-RSA-CHACHA20-POLY1305:"
168 "ECDHE-ECDSA-AES128-GCM-SHA256:"
169 "ECDHE-RSA-AES128-GCM-SHA256",
170 {
171 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500172 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
173 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800174 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500175 },
176 // Multiple masks can be ANDed in a single rule.
177 {
178 "kRSA+AESGCM+AES128",
179 {
180 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
181 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800182 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500183 },
184 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700185 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500186 // ECDHE_RSA.
187 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700188 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700189 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500190 "AESGCM+AES128+aRSA",
191 {
192 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500193 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
194 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800195 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500196 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800197 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500198 {
199 "ECDHE-ECDSA-CHACHA20-POLY1305:"
200 "ECDHE-RSA-CHACHA20-POLY1305:"
201 "ECDHE-ECDSA-AES128-GCM-SHA256:"
202 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800203 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500204 {
205 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500206 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500207 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
208 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
209 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800210 true,
211 },
212 // Unknown selectors are no-ops, except in strict mode.
213 {
214 "ECDHE-ECDSA-CHACHA20-POLY1305:"
215 "ECDHE-RSA-CHACHA20-POLY1305:"
216 "ECDHE-ECDSA-AES128-GCM-SHA256:"
217 "ECDHE-RSA-AES128-GCM-SHA256:"
218 "-BOGUS2:+BOGUS3:!BOGUS4",
219 {
220 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
222 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
223 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
224 },
225 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500226 },
227 // Square brackets specify equi-preference groups.
228 {
229 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
230 "[ECDHE-RSA-CHACHA20-POLY1305]:"
231 "ECDHE-RSA-AES128-GCM-SHA256",
232 {
233 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500234 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800235 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500236 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
237 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800238 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500239 },
David Benjamin6fff3862017-06-21 21:07:04 -0400240 // Standard names may be used instead of OpenSSL names.
241 {
242 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400243 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400244 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
245 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
246 {
247 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
248 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
249 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
250 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
251 },
252 false,
253 },
David Benjaminfb974e62015-12-16 19:34:22 -0500254 // @STRENGTH performs a stable strength-sort of the selected ciphers and
255 // only the selected ciphers.
256 {
257 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700258 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400259 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500260 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700261 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500262 // Select ECDHE ones and sort them by strength. Ties should resolve
263 // based on the order above.
264 "kECDHE:@STRENGTH:-ALL:"
265 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
266 // by strength. Then RSA, backwards by strength.
267 "aRSA",
268 {
269 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
270 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500271 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500272 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
273 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
274 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800275 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500276 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400277 // Additional masks after @STRENGTH get silently discarded.
278 //
279 // TODO(davidben): Make this an error. If not silently discarded, they get
280 // interpreted as + opcodes which are very different.
281 {
282 "ECDHE-RSA-AES128-GCM-SHA256:"
283 "ECDHE-RSA-AES256-GCM-SHA384:"
284 "@STRENGTH+AES256",
285 {
286 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
287 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
288 },
289 false,
290 },
291 {
292 "ECDHE-RSA-AES128-GCM-SHA256:"
293 "ECDHE-RSA-AES256-GCM-SHA384:"
294 "@STRENGTH+AES256:"
295 "ECDHE-RSA-CHACHA20-POLY1305",
296 {
297 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
298 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
299 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
300 },
301 false,
302 },
David Benjaminfb974e62015-12-16 19:34:22 -0500303 // Exact ciphers may not be used in multi-part rules; they are treated
304 // as unknown aliases.
305 {
306 "ECDHE-ECDSA-AES128-GCM-SHA256:"
307 "ECDHE-RSA-AES128-GCM-SHA256:"
308 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
309 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
310 {
311 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
312 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
313 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800314 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500315 },
316 // SSLv3 matches everything that existed before TLS 1.2.
317 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400318 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500319 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400320 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500321 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800322 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500323 },
324 // TLSv1.2 matches everything added in TLS 1.2.
325 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400326 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500327 {
328 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
329 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800330 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500331 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800332 // The two directives have no intersection. But each component is valid, so
333 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500334 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400335 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500336 {
337 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400338 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500339 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800340 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500341 },
Adam Langley22df6912017-07-25 12:27:37 -0700342 // Spaces, semi-colons and commas are separators.
343 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400344 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700345 {
346 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400347 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700348 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400349 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700350 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
351 },
352 // …but not in strict mode.
353 true,
354 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400355};
356
357static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400358 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400359 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
360 "RSA]",
361 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400362 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400363 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400364 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400365 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400366 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400367 "",
368 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400369 // COMPLEMENTOFDEFAULT is empty.
370 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400371 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400372 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400373 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400374 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
375 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
376 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
377 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700378 // Opcode supplied, but missing selector.
379 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700380 // Spaces are forbidden in equal-preference groups.
381 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400382};
383
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700384static const char *kMustNotIncludeNull[] = {
385 "ALL",
386 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500387 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700388 "FIPS",
389 "SHA",
390 "SHA1",
391 "RSA",
392 "SSLv3",
393 "TLSv1",
394 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700395};
396
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100397static const CurveTest kCurveTests[] = {
398 {
399 "P-256",
400 { SSL_CURVE_SECP256R1 },
401 },
402 {
Adam Langley7b935932018-11-12 13:53:42 -0800403 "P-256:CECPQ2",
404 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
405 },
406
407 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100408 "P-256:P-384:P-521:X25519",
409 {
410 SSL_CURVE_SECP256R1,
411 SSL_CURVE_SECP384R1,
412 SSL_CURVE_SECP521R1,
413 SSL_CURVE_X25519,
414 },
415 },
David Benjamin6dda1662017-11-02 20:44:26 -0400416 {
417 "prime256v1:secp384r1:secp521r1:x25519",
418 {
419 SSL_CURVE_SECP256R1,
420 SSL_CURVE_SECP384R1,
421 SSL_CURVE_SECP521R1,
422 SSL_CURVE_X25519,
423 },
424 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100425};
426
427static const char *kBadCurvesLists[] = {
428 "",
429 ":",
430 "::",
431 "P-256::X25519",
432 "RSA:P-256",
433 "P-256:RSA",
434 "X25519:P-256:",
435 ":X25519:P-256",
436};
437
David Benjamin70dbf042017-08-08 18:51:37 -0400438static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400439 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400440 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400441 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
442 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
443 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
444 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400446 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447 }
David Benjamine11726a2017-04-23 12:14:28 -0400448 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400449 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400450 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400451 }
David Benjamine11726a2017-04-23 12:14:28 -0400452 ret += SSL_CIPHER_get_name(cipher);
453 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400454 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400455 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400456 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400457 }
458 }
David Benjamine11726a2017-04-23 12:14:28 -0400459 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400460}
461
David Benjamin70dbf042017-08-08 18:51:37 -0400462static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400463 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400464 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
465 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400466 return false;
David Benjamin65226252015-02-05 16:49:47 -0500467 }
468
David Benjamine11726a2017-04-23 12:14:28 -0400469 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400470 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400471 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400472 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400473 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400474 }
475 }
476
David Benjamin1d77e562015-03-22 17:22:08 -0400477 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400478}
479
Daniel McArdleff746c12019-09-16 12:35:05 -0400480TEST(GrowableArrayTest, Resize) {
481 GrowableArray<size_t> array;
482 ASSERT_TRUE(array.empty());
483 EXPECT_EQ(array.size(), 0u);
484
485 ASSERT_TRUE(array.Push(42));
486 ASSERT_TRUE(!array.empty());
487 EXPECT_EQ(array.size(), 1u);
488
489 // Force a resize operation to occur
490 for (size_t i = 0; i < 16; i++) {
491 ASSERT_TRUE(array.Push(i + 1));
492 }
493
494 EXPECT_EQ(array.size(), 17u);
495
496 // Verify that expected values are still contained in array
497 for (size_t i = 0; i < array.size(); i++) {
498 EXPECT_EQ(array[i], i == 0 ? 42 : i);
499 }
500}
501
502TEST(GrowableArrayTest, MoveConstructor) {
503 GrowableArray<size_t> array;
504 for (size_t i = 0; i < 100; i++) {
505 ASSERT_TRUE(array.Push(i));
506 }
507
508 GrowableArray<size_t> array_moved(std::move(array));
509 for (size_t i = 0; i < 100; i++) {
510 EXPECT_EQ(array_moved[i], i);
511 }
512}
513
514TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
515 // Representative example of a struct that contains a GrowableArray.
516 struct TagAndArray {
517 size_t tag;
518 GrowableArray<size_t> array;
519 };
520
521 GrowableArray<TagAndArray> array;
522 for (size_t i = 0; i < 100; i++) {
523 TagAndArray elem;
524 elem.tag = i;
525 for (size_t j = 0; j < i; j++) {
526 ASSERT_TRUE(elem.array.Push(j));
527 }
528 ASSERT_TRUE(array.Push(std::move(elem)));
529 }
530 EXPECT_EQ(array.size(), static_cast<size_t>(100));
531
532 GrowableArray<TagAndArray> array_moved(std::move(array));
533 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
534 size_t count = 0;
535 for (const TagAndArray &elem : array_moved) {
536 // Test the square bracket operator returns the same value as iteration.
537 EXPECT_EQ(&elem, &array_moved[count]);
538
539 EXPECT_EQ(elem.tag, count);
540 EXPECT_EQ(elem.array.size(), count);
541 for (size_t j = 0; j < count; j++) {
542 EXPECT_EQ(elem.array[j], j);
543 }
544 count++;
545 }
546}
547
David Benjamine11726a2017-04-23 12:14:28 -0400548TEST(SSLTest, CipherRules) {
549 for (const CipherTest &t : kCipherTests) {
550 SCOPED_TRACE(t.rule);
551 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
552 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700553
David Benjamine11726a2017-04-23 12:14:28 -0400554 // Test lax mode.
555 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400556 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400557 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400558 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400559
560 // Test strict mode.
561 if (t.strict_fail) {
562 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
563 } else {
564 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400565 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400566 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400567 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400568 }
569 }
570
David Benjaminfb974e62015-12-16 19:34:22 -0500571 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400572 SCOPED_TRACE(rule);
573 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
574 ASSERT_TRUE(ctx);
575
576 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400577 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400578 }
579
David Benjaminfb974e62015-12-16 19:34:22 -0500580 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400581 SCOPED_TRACE(rule);
582 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
583 ASSERT_TRUE(ctx);
584
585 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400586 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700587 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700588 }
589 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400590}
David Benjamin2e521212014-07-16 14:37:51 -0400591
David Benjamine11726a2017-04-23 12:14:28 -0400592TEST(SSLTest, CurveRules) {
593 for (const CurveTest &t : kCurveTests) {
594 SCOPED_TRACE(t.rule);
595 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
596 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100597
David Benjamine11726a2017-04-23 12:14:28 -0400598 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400599 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400600 for (size_t i = 0; i < t.expected.size(); i++) {
601 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100602 }
603 }
604
605 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400606 SCOPED_TRACE(rule);
607 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
608 ASSERT_TRUE(ctx);
609
610 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100611 ERR_clear_error();
612 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100613}
614
Adam Langley364f7a62016-12-12 10:51:00 -0800615// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700616static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800617 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700618 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
619 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
620 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
621 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
622 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
623 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
624 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
625 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
626 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
627 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
628 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
629 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
630 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
631 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
632 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
633 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
634 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
635 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
636 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
637 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
638 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
639 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
640 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
641 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
642 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
643 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
644 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
645 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
646 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800647 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700648
649// kCustomSession is a custom serialized SSL_SESSION generated by
650// filling in missing fields from |kOpenSSLSession|. This includes
651// providing |peer_sha256|, so |peer| is not serialized.
652static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400653 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700654 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400655 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
656 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
657 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
658 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
659 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
660 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700661
662// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
663static const char kBoringSSLSession[] =
664 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
665 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
666 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
667 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
668 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
669 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
670 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
671 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
672 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
673 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
674 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
675 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
676 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
677 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
678 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
679 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
680 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
681 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
682 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
683 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
684 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
685 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
686 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
687 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
688 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
689 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
690 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
691 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
692 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
693 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
694 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
695 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
696 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
697 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
698 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
699 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
700 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
701 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
702 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
703 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
704 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
705 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
706 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
707 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
708 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
709 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
710 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
711 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
712 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
713 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
714 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
715 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
716 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
717 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
718 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
719 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
720 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
721 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
722 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
723 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
724 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
725 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
726 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
727 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
728 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
729 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
730 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
731 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
732 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
733 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
734 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
735 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
736 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
737 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
738 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
739 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
740 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
741 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
742 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
743 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
744 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
745 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
746 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
747 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
748 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
749 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
750 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
751 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
752 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
753 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
754 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
755 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
756 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
757 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
758 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
759
760// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400761// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700762static const char kBadSessionExtraField[] =
763 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
764 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
765 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
766 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
767 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
768 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
769 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400770 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700771
772// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
773// the version of |kCustomSession| with 2.
774static const char kBadSessionVersion[] =
775 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
776 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
777 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
778 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
779 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
780 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
781 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
782 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
783
784// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
785// appended.
786static const char kBadSessionTrailingData[] =
787 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
788 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
789 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
790 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
791 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
792 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
793 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
794 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
795
David Benjamin1d77e562015-03-22 17:22:08 -0400796static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400797 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400798 if (!EVP_DecodedLength(&len, strlen(in))) {
799 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400800 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400801 }
802
David Benjamin1d77e562015-03-22 17:22:08 -0400803 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800804 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400805 strlen(in))) {
806 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400807 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400808 }
David Benjamin1d77e562015-03-22 17:22:08 -0400809 out->resize(len);
810 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400811}
812
David Benjamina486c6c2019-03-28 18:32:38 -0500813TEST(SSLTest, SessionEncoding) {
814 for (const char *input_b64 : {
815 kOpenSSLSession,
816 kCustomSession,
817 kBoringSSLSession,
818 }) {
819 SCOPED_TRACE(std::string(input_b64));
820 // Decode the input.
821 std::vector<uint8_t> input;
822 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400823
David Benjamina486c6c2019-03-28 18:32:38 -0500824 // Verify the SSL_SESSION decodes.
825 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
826 ASSERT_TRUE(ssl_ctx);
827 bssl::UniquePtr<SSL_SESSION> session(
828 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
829 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
830
831 // Verify the SSL_SESSION encoding round-trips.
832 size_t encoded_len;
833 bssl::UniquePtr<uint8_t> encoded;
834 uint8_t *encoded_raw;
835 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
836 << "SSL_SESSION_to_bytes failed";
837 encoded.reset(encoded_raw);
838 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
839 << "SSL_SESSION_to_bytes did not round-trip";
840
841 // Verify the SSL_SESSION also decodes with the legacy API.
842 const uint8_t *cptr = input.data();
843 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
844 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
845 EXPECT_EQ(cptr, input.data() + input.size());
846
847 // Verify the SSL_SESSION encoding round-trips via the legacy API.
848 int len = i2d_SSL_SESSION(session.get(), NULL);
849 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
850 ASSERT_EQ(static_cast<size_t>(len), input.size())
851 << "i2d_SSL_SESSION(NULL) returned invalid length";
852
853 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
854 ASSERT_TRUE(encoded);
855
856 uint8_t *ptr = encoded.get();
857 len = i2d_SSL_SESSION(session.get(), &ptr);
858 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
859 ASSERT_EQ(static_cast<size_t>(len), input.size())
860 << "i2d_SSL_SESSION(NULL) returned invalid length";
861 ASSERT_EQ(ptr, encoded.get() + input.size())
862 << "i2d_SSL_SESSION did not advance ptr correctly";
863 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
864 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400865 }
866
David Benjamina486c6c2019-03-28 18:32:38 -0500867 for (const char *input_b64 : {
868 kBadSessionExtraField,
869 kBadSessionVersion,
870 kBadSessionTrailingData,
871 }) {
872 SCOPED_TRACE(std::string(input_b64));
873 std::vector<uint8_t> input;
874 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400875
David Benjamina486c6c2019-03-28 18:32:38 -0500876 // Verify that the SSL_SESSION fails to decode.
877 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
878 ASSERT_TRUE(ssl_ctx);
879 bssl::UniquePtr<SSL_SESSION> session(
880 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
881 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
882 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400883 }
David Benjaminf297e022015-05-28 19:55:29 -0400884}
885
David Benjamin321fcdc2017-04-24 11:42:42 -0400886static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
887 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700888 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400889 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700890 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
891 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400892}
893
894TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800895 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400896 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
897 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
898 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700899 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
900 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
901 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500902}
903
David Benjamin348f0d82017-08-10 16:06:27 -0400904TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400905 static const struct {
906 int id;
907 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400908 int cipher_nid;
909 int digest_nid;
910 int kx_nid;
911 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400912 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400913 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400914 {
915 SSL3_CK_RSA_DES_192_CBC3_SHA,
916 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
917 NID_des_ede3_cbc,
918 NID_sha1,
919 NID_kx_rsa,
920 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400921 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400922 },
923 {
924 TLS1_CK_RSA_WITH_AES_128_SHA,
925 "TLS_RSA_WITH_AES_128_CBC_SHA",
926 NID_aes_128_cbc,
927 NID_sha1,
928 NID_kx_rsa,
929 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400930 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400931 },
932 {
933 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
934 "TLS_PSK_WITH_AES_256_CBC_SHA",
935 NID_aes_256_cbc,
936 NID_sha1,
937 NID_kx_psk,
938 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400939 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400940 },
941 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400942 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
943 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400944 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400945 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400946 NID_kx_ecdhe,
947 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400948 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400949 },
950 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400951 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
952 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400953 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400954 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400955 NID_kx_ecdhe,
956 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400957 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400958 },
959 {
960 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
961 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
962 NID_aes_128_gcm,
963 NID_undef,
964 NID_kx_ecdhe,
965 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400966 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400967 },
968 {
969 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
970 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
971 NID_aes_128_gcm,
972 NID_undef,
973 NID_kx_ecdhe,
974 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400975 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400976 },
977 {
978 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
979 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
980 NID_aes_256_gcm,
981 NID_undef,
982 NID_kx_ecdhe,
983 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400984 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400985 },
986 {
987 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
988 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
989 NID_aes_128_cbc,
990 NID_sha1,
991 NID_kx_ecdhe,
992 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400993 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400994 },
995 {
996 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
997 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
998 NID_chacha20_poly1305,
999 NID_undef,
1000 NID_kx_ecdhe,
1001 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001002 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001003 },
1004 {
David Benjamindfddbc42022-07-18 16:08:06 -04001005 TLS1_3_CK_AES_256_GCM_SHA384,
David Benjamin348f0d82017-08-10 16:06:27 -04001006 "TLS_AES_256_GCM_SHA384",
1007 NID_aes_256_gcm,
1008 NID_undef,
1009 NID_kx_any,
1010 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001011 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001012 },
1013 {
David Benjamindfddbc42022-07-18 16:08:06 -04001014 TLS1_3_CK_AES_128_GCM_SHA256,
David Benjamin348f0d82017-08-10 16:06:27 -04001015 "TLS_AES_128_GCM_SHA256",
1016 NID_aes_128_gcm,
1017 NID_undef,
1018 NID_kx_any,
1019 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001020 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001021 },
1022 {
David Benjamindfddbc42022-07-18 16:08:06 -04001023 TLS1_3_CK_CHACHA20_POLY1305_SHA256,
David Benjamin348f0d82017-08-10 16:06:27 -04001024 "TLS_CHACHA20_POLY1305_SHA256",
1025 NID_chacha20_poly1305,
1026 NID_undef,
1027 NID_kx_any,
1028 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001029 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001030 },
David Benjamin6fff3862017-06-21 21:07:04 -04001031 };
David Benjamin65226252015-02-05 16:49:47 -05001032
David Benjamin6fff3862017-06-21 21:07:04 -04001033 for (const auto &t : kTests) {
1034 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001035
1036 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1037 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001038 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1039
David Benjamine11726a2017-04-23 12:14:28 -04001040 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1041 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001042 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001043
1044 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1045 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1046 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1047 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001048 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001049 }
David Benjamin65226252015-02-05 16:49:47 -05001050}
1051
Steven Valdeza833c352016-11-01 13:39:36 -04001052// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1053// version and ticket length or nullptr on failure.
1054static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1055 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001056 std::vector<uint8_t> der;
1057 if (!DecodeBase64(&der, kOpenSSLSession)) {
1058 return nullptr;
1059 }
Adam Langley46db7af2017-02-01 15:49:37 -08001060
1061 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1062 if (!ssl_ctx) {
1063 return nullptr;
1064 }
David Benjaminaaef8332018-06-29 16:45:49 -04001065 // Use a garbage ticket.
1066 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001067 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001068 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001069 if (!session ||
1070 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1071 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001072 return nullptr;
1073 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001074 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001075#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001076 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001077#else
David Benjaminaaef8332018-06-29 16:45:49 -04001078 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001079#endif
David Benjamin422fe082015-07-21 22:03:43 -04001080 return session;
1081}
1082
David Benjaminafc64de2016-07-19 17:12:41 +02001083static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001084 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001085 if (!bio) {
1086 return false;
1087 }
1088 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001089 BIO_up_ref(bio.get());
1090 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001091 int ret = SSL_connect(ssl);
1092 if (ret > 0) {
1093 // SSL_connect should fail without a BIO to write to.
1094 return false;
1095 }
1096 ERR_clear_error();
1097
1098 const uint8_t *client_hello;
1099 size_t client_hello_len;
1100 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1101 return false;
1102 }
1103 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1104 return true;
1105}
1106
Steven Valdeza833c352016-11-01 13:39:36 -04001107// GetClientHelloLen creates a client SSL connection with the specified version
1108// and ticket length. It returns the length of the ClientHello, not including
1109// the record header, on success and zero on error.
1110static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1111 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001112 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001113 bssl::UniquePtr<SSL_SESSION> session =
1114 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001115 if (!ctx || !session) {
1116 return 0;
1117 }
Steven Valdeza833c352016-11-01 13:39:36 -04001118
1119 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001120 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001121 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001122 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001123 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001124 return 0;
1125 }
Steven Valdeza833c352016-11-01 13:39:36 -04001126
David Benjaminafc64de2016-07-19 17:12:41 +02001127 std::vector<uint8_t> client_hello;
1128 if (!GetClientHello(ssl.get(), &client_hello) ||
1129 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001130 return 0;
1131 }
Steven Valdeza833c352016-11-01 13:39:36 -04001132
David Benjaminafc64de2016-07-19 17:12:41 +02001133 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001134}
1135
David Benjamina486c6c2019-03-28 18:32:38 -05001136TEST(SSLTest, Padding) {
1137 struct PaddingVersions {
1138 uint16_t max_version, session_version;
1139 };
1140 static const PaddingVersions kPaddingVersions[] = {
1141 // Test the padding extension at TLS 1.2.
1142 {TLS1_2_VERSION, TLS1_2_VERSION},
1143 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1144 // will be no PSK binder after the padding extension.
1145 {TLS1_3_VERSION, TLS1_2_VERSION},
1146 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1147 // will be a PSK binder after the padding extension.
1148 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001149
David Benjamina486c6c2019-03-28 18:32:38 -05001150 };
David Benjamin422fe082015-07-21 22:03:43 -04001151
David Benjamina486c6c2019-03-28 18:32:38 -05001152 struct PaddingTest {
1153 size_t input_len, padded_len;
1154 };
1155 static const PaddingTest kPaddingTests[] = {
1156 // ClientHellos of length below 0x100 do not require padding.
1157 {0xfe, 0xfe},
1158 {0xff, 0xff},
1159 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1160 {0x100, 0x200},
1161 {0x123, 0x200},
1162 {0x1fb, 0x200},
1163 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1164 // padding extension takes a minimum of four bytes plus one required
1165 // content
1166 // byte. (To work around yet more server bugs, we avoid empty final
1167 // extensions.)
1168 {0x1fc, 0x201},
1169 {0x1fd, 0x202},
1170 {0x1fe, 0x203},
1171 {0x1ff, 0x204},
1172 // Finally, larger ClientHellos need no padding.
1173 {0x200, 0x200},
1174 {0x201, 0x201},
1175 };
David Benjamin422fe082015-07-21 22:03:43 -04001176
David Benjamina486c6c2019-03-28 18:32:38 -05001177 for (const PaddingVersions &versions : kPaddingVersions) {
1178 SCOPED_TRACE(versions.max_version);
1179 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001180
David Benjamina486c6c2019-03-28 18:32:38 -05001181 // Sample a baseline length.
1182 size_t base_len =
1183 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1184 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1185
1186 for (const PaddingTest &test : kPaddingTests) {
1187 SCOPED_TRACE(test.input_len);
1188 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1189
1190 size_t padded_len =
1191 GetClientHelloLen(versions.max_version, versions.session_version,
1192 1 + test.input_len - base_len);
1193 EXPECT_EQ(padded_len, test.padded_len)
1194 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001195 }
1196 }
David Benjamin422fe082015-07-21 22:03:43 -04001197}
1198
David Benjamin2f3958a2021-04-16 11:55:23 -04001199static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1200 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1201 if (!bio) {
1202 return nullptr;
1203 }
1204 return bssl::UniquePtr<X509>(
1205 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1206}
1207
1208static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1209 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1210 if (!bio) {
1211 return nullptr;
1212 }
1213 return bssl::UniquePtr<EVP_PKEY>(
1214 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1215}
1216
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001217static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001218 static const char kCertPEM[] =
1219 "-----BEGIN CERTIFICATE-----\n"
1220 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1221 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1222 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1223 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1224 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1225 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1226 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1227 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1228 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1229 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1230 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1231 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1232 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1233 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001234 return CertFromPEM(kCertPEM);
David Benjaminde942382016-02-11 12:02:01 -05001235}
1236
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001237static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001238 static const char kKeyPEM[] =
1239 "-----BEGIN RSA PRIVATE KEY-----\n"
1240 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1241 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1242 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1243 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1244 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1245 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1246 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1247 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1248 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1249 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1250 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1251 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1252 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1253 "-----END RSA PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001254 return KeyFromPEM(kKeyPEM);
David Benjaminde942382016-02-11 12:02:01 -05001255}
1256
David Benjamin9b2cdb72021-04-01 23:21:53 -04001257static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1258 const SSL_METHOD *method) {
1259 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1260 bssl::UniquePtr<X509> cert = GetTestCertificate();
1261 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1262 if (!ctx || !cert || !key ||
1263 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1264 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1265 return nullptr;
1266 }
1267 return ctx;
1268}
1269
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001270static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001271 static const char kCertPEM[] =
1272 "-----BEGIN CERTIFICATE-----\n"
1273 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1274 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1275 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1276 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1277 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1278 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1279 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1280 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1281 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1282 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1283 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001284 return CertFromPEM(kCertPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001285}
1286
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001287static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001288 static const char kKeyPEM[] =
1289 "-----BEGIN PRIVATE KEY-----\n"
1290 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1291 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1292 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1293 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001294 return KeyFromPEM(kKeyPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001295}
1296
Adam Langleyd04ca952017-02-28 11:26:51 -08001297static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1298 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1299 char *name, *header;
1300 uint8_t *data;
1301 long data_len;
1302 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1303 &data_len)) {
1304 return nullptr;
1305 }
1306 OPENSSL_free(name);
1307 OPENSSL_free(header);
1308
1309 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1310 CRYPTO_BUFFER_new(data, data_len, nullptr));
1311 OPENSSL_free(data);
1312 return ret;
1313}
1314
1315static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001316 static const char kCertPEM[] =
1317 "-----BEGIN CERTIFICATE-----\n"
1318 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1319 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1320 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1321 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1322 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1323 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1324 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1325 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1326 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1327 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1328 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1329 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1330 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1331 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1332 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1333 "1ngWZ7Ih\n"
1334 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001335 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001336}
1337
Adam Langleyd04ca952017-02-28 11:26:51 -08001338static bssl::UniquePtr<X509> X509FromBuffer(
1339 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1340 if (!buffer) {
1341 return nullptr;
1342 }
1343 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1344 return bssl::UniquePtr<X509>(
1345 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1346}
1347
1348static bssl::UniquePtr<X509> GetChainTestCertificate() {
1349 return X509FromBuffer(GetChainTestCertificateBuffer());
1350}
1351
1352static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001353 static const char kCertPEM[] =
1354 "-----BEGIN CERTIFICATE-----\n"
1355 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1356 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1357 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1358 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1359 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1360 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1361 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1362 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1363 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1364 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1365 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1366 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1367 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1368 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1369 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1370 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001371 return BufferFromPEM(kCertPEM);
1372}
1373
1374static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1375 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001376}
1377
1378static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1379 static const char kKeyPEM[] =
1380 "-----BEGIN PRIVATE KEY-----\n"
1381 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1382 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1383 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1384 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1385 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1386 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1387 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1388 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1389 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1390 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1391 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1392 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1393 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1394 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1395 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1396 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1397 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1398 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1399 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1400 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1401 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1402 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1403 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1404 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1405 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1406 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1407 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001408 return KeyFromPEM(kKeyPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001409}
1410
David Benjamin83a49932021-05-20 15:57:09 -04001411static bool CompleteHandshakes(SSL *client, SSL *server) {
1412 // Drive both their handshakes to completion.
1413 for (;;) {
1414 int client_ret = SSL_do_handshake(client);
1415 int client_err = SSL_get_error(client, client_ret);
1416 if (client_err != SSL_ERROR_NONE &&
1417 client_err != SSL_ERROR_WANT_READ &&
1418 client_err != SSL_ERROR_WANT_WRITE &&
1419 client_err != SSL_ERROR_PENDING_TICKET) {
1420 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
1421 return false;
1422 }
1423
1424 int server_ret = SSL_do_handshake(server);
1425 int server_err = SSL_get_error(server, server_ret);
1426 if (server_err != SSL_ERROR_NONE &&
1427 server_err != SSL_ERROR_WANT_READ &&
1428 server_err != SSL_ERROR_WANT_WRITE &&
1429 server_err != SSL_ERROR_PENDING_TICKET) {
1430 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
1431 return false;
1432 }
1433
1434 if (client_ret == 1 && server_ret == 1) {
1435 break;
1436 }
1437 }
1438
1439 return true;
1440}
1441
1442static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1443 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1444 // not pick them up until |SSL_read|.
1445 for (;;) {
1446 int server_ret = SSL_write(server, nullptr, 0);
1447 int server_err = SSL_get_error(server, server_ret);
1448 // The server may either succeed (|server_ret| is zero) or block on write
1449 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1450 if (server_ret > 0 ||
1451 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1452 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1453 server_err);
1454 return false;
1455 }
1456
1457 int client_ret = SSL_read(client, nullptr, 0);
1458 int client_err = SSL_get_error(client, client_ret);
1459 // The client must always block on read.
1460 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1461 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1462 client_err);
1463 return false;
1464 }
1465
1466 // The server flushed everything it had to write.
1467 if (server_ret == 0) {
1468 return true;
1469 }
1470 }
1471}
1472
1473// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1474// are paired with each other. It does not run the handshake. The caller is
1475// expected to configure the objects and drive the handshake as needed.
1476static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1477 bssl::UniquePtr<SSL> *out_server,
1478 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1479 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1480 if (!client || !server) {
1481 return false;
1482 }
1483 SSL_set_connect_state(client.get());
1484 SSL_set_accept_state(server.get());
1485
1486 BIO *bio1, *bio2;
1487 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1488 return false;
1489 }
1490 // SSL_set_bio takes ownership.
1491 SSL_set_bio(client.get(), bio1, bio1);
1492 SSL_set_bio(server.get(), bio2, bio2);
1493
1494 *out_client = std::move(client);
1495 *out_server = std::move(server);
1496 return true;
1497}
1498
1499struct ClientConfig {
1500 SSL_SESSION *session = nullptr;
1501 std::string servername;
Adam Langley7e7e6b62021-12-06 13:04:07 -08001502 std::string verify_hostname;
1503 unsigned hostflags = 0;
David Benjamin83a49932021-05-20 15:57:09 -04001504 bool early_data = false;
1505};
1506
1507static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1508 bssl::UniquePtr<SSL> *out_server,
1509 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1510 const ClientConfig &config = ClientConfig(),
1511 bool shed_handshake_config = true) {
1512 bssl::UniquePtr<SSL> client, server;
1513 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
1514 return false;
1515 }
1516 if (config.early_data) {
1517 SSL_set_early_data_enabled(client.get(), 1);
1518 }
1519 if (config.session) {
1520 SSL_set_session(client.get(), config.session);
1521 }
1522 if (!config.servername.empty() &&
1523 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1524 return false;
1525 }
Adam Langley7e7e6b62021-12-06 13:04:07 -08001526 if (!config.verify_hostname.empty()) {
1527 if (!SSL_set1_host(client.get(), config.verify_hostname.c_str())) {
1528 return false;
1529 }
1530 SSL_set_hostflags(client.get(), config.hostflags);
1531 }
David Benjamin83a49932021-05-20 15:57:09 -04001532
1533 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1534 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1535
1536 if (!CompleteHandshakes(client.get(), server.get())) {
1537 return false;
1538 }
1539
1540 *out_client = std::move(client);
1541 *out_server = std::move(server);
1542 return true;
1543}
1544
David Benjamin9734e442021-06-15 13:58:12 -04001545static bssl::UniquePtr<SSL_SESSION> g_last_session;
1546
1547static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1548 // Save the most recent session.
1549 g_last_session.reset(session);
1550 return 1;
1551}
1552
1553static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
1554 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1555 const ClientConfig &config = ClientConfig()) {
1556 g_last_session = nullptr;
1557 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1558
1559 // Connect client and server to get a session.
1560 bssl::UniquePtr<SSL> client, server;
1561 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1562 config) ||
1563 !FlushNewSessionTickets(client.get(), server.get())) {
1564 fprintf(stderr, "Failed to connect client and server.\n");
1565 return nullptr;
1566 }
1567
1568 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1569
1570 if (!g_last_session) {
1571 fprintf(stderr, "Client did not receive a session.\n");
1572 return nullptr;
1573 }
1574 return std::move(g_last_session);
1575}
1576
David Benjaminc79ae7a2017-08-29 16:09:44 -04001577// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1578// before configuring as a server.
1579TEST(SSLTest, ClientCAList) {
1580 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1581 ASSERT_TRUE(ctx);
1582 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1583 ASSERT_TRUE(ssl);
1584
1585 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1586 ASSERT_TRUE(name);
1587
1588 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1589 ASSERT_TRUE(name_dup);
1590
1591 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1592 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001593 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001594
1595 // |SSL_set_client_CA_list| takes ownership.
1596 SSL_set_client_CA_list(ssl.get(), stack.release());
1597
1598 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1599 ASSERT_TRUE(result);
1600 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1601 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1602}
1603
1604TEST(SSLTest, AddClientCA) {
1605 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1606 ASSERT_TRUE(ctx);
1607 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1608 ASSERT_TRUE(ssl);
1609
1610 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1611 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1612 ASSERT_TRUE(cert1 && cert2);
1613 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1614 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1615
1616 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1617
1618 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1619 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1620
1621 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1622 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1623 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1624 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1625
1626 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1627
1628 list = SSL_get_client_CA_list(ssl.get());
1629 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1630 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1631 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1632 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1633}
1634
David Benjamin24545c52021-06-07 16:05:07 -04001635struct ECHConfigParams {
1636 uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1637 uint16_t config_id = 1;
1638 std::string public_name = "example.com";
1639 const EVP_HPKE_KEY *key = nullptr;
1640 // kem_id, if zero, takes its value from |key|.
1641 uint16_t kem_id = 0;
1642 // public_key, if empty takes its value from |key|.
1643 std::vector<uint8_t> public_key;
1644 size_t max_name_len = 16;
1645 // cipher_suites is a list of code points which should contain pairs of KDF
1646 // and AEAD IDs.
1647 std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1648 EVP_HPKE_AES_128_GCM};
1649 std::vector<uint8_t> extensions;
1650};
Daniel McArdle00e434d2021-02-18 11:47:18 -05001651
David Benjamin24545c52021-06-07 16:05:07 -04001652// MakeECHConfig serializes an ECHConfig from |params| and writes it to
1653// |*out|.
1654bool MakeECHConfig(std::vector<uint8_t> *out,
1655 const ECHConfigParams &params) {
1656 uint16_t kem_id = params.kem_id == 0
1657 ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1658 : params.kem_id;
1659 std::vector<uint8_t> public_key = params.public_key;
1660 if (public_key.empty()) {
1661 public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1662 size_t len;
1663 if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1664 public_key.size())) {
1665 return false;
1666 }
1667 public_key.resize(len);
1668 }
Daniel McArdle00e434d2021-02-18 11:47:18 -05001669
Daniel McArdle00e434d2021-02-18 11:47:18 -05001670 bssl::ScopedCBB cbb;
1671 CBB contents, child;
Daniel McArdle00e434d2021-02-18 11:47:18 -05001672 if (!CBB_init(cbb.get(), 64) ||
David Benjamin24545c52021-06-07 16:05:07 -04001673 !CBB_add_u16(cbb.get(), params.version) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001674 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
David Benjamin24545c52021-06-07 16:05:07 -04001675 !CBB_add_u8(&contents, params.config_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001676 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001677 !CBB_add_u16_length_prefixed(&contents, &child) ||
1678 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001679 !CBB_add_u16_length_prefixed(&contents, &child)) {
1680 return false;
1681 }
David Benjamin24545c52021-06-07 16:05:07 -04001682 for (uint16_t cipher_suite : params.cipher_suites) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001683 if (!CBB_add_u16(&child, cipher_suite)) {
1684 return false;
1685 }
1686 }
David Benjamin18b68362021-06-18 23:13:46 -04001687 if (!CBB_add_u8(&contents, params.max_name_len) ||
1688 !CBB_add_u8_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001689 !CBB_add_bytes(
1690 &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1691 params.public_name.size()) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001692 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001693 !CBB_add_bytes(&child, params.extensions.data(),
1694 params.extensions.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001695 !CBB_flush(cbb.get())) {
1696 return false;
1697 }
1698
1699 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1700 return true;
1701}
1702
David Benjaminba423c92021-06-15 16:26:58 -04001703static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys(uint8_t config_id = 1) {
David Benjamin83a49932021-05-20 15:57:09 -04001704 bssl::ScopedEVP_HPKE_KEY key;
1705 uint8_t *ech_config;
1706 size_t ech_config_len;
1707 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
David Benjaminba423c92021-06-15 16:26:58 -04001708 !SSL_marshal_ech_config(&ech_config, &ech_config_len, config_id,
1709 key.get(), "public.example", 16)) {
David Benjamin83a49932021-05-20 15:57:09 -04001710 return nullptr;
1711 }
1712 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1713
1714 // Install a non-retry config.
1715 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1716 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1717 ech_config_len, key.get())) {
1718 return nullptr;
1719 }
1720 return keys;
1721}
1722
1723static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1724 uint8_t *ech_config_list;
1725 size_t ech_config_list_len;
1726 if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1727 &ech_config_list_len)) {
1728 return false;
1729 }
1730 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1731 return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1732}
1733
David Benjamin24545c52021-06-07 16:05:07 -04001734// Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1735// output values as expected.
1736TEST(SSLTest, MarshalECHConfig) {
1737 static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1738 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1739 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1740 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1741 bssl::ScopedEVP_HPKE_KEY key;
1742 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1743 kPrivateKey, sizeof(kPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001744
David Benjamin24545c52021-06-07 16:05:07 -04001745 static const uint8_t kECHConfig[] = {
1746 // version
David Benjamin18b68362021-06-18 23:13:46 -04001747 0xfe, 0x0d,
David Benjamin24545c52021-06-07 16:05:07 -04001748 // length
David Benjamin18b68362021-06-18 23:13:46 -04001749 0x00, 0x41,
David Benjamin24545c52021-06-07 16:05:07 -04001750 // contents.config_id
1751 0x01,
1752 // contents.kem_id
1753 0x00, 0x20,
1754 // contents.public_key
1755 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1756 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1757 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1758 // contents.cipher_suites
1759 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1760 // contents.maximum_name_length
David Benjamin18b68362021-06-18 23:13:46 -04001761 0x10,
David Benjamin24545c52021-06-07 16:05:07 -04001762 // contents.public_name
David Benjamin18b68362021-06-18 23:13:46 -04001763 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
1764 0x70, 0x6c, 0x65,
David Benjamin24545c52021-06-07 16:05:07 -04001765 // contents.extensions
1766 0x00, 0x00};
1767 uint8_t *ech_config;
1768 size_t ech_config_len;
1769 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1770 /*config_id=*/1, key.get(),
1771 "public.example", 16));
1772 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1773 EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1774
1775 // Generate a second ECHConfig.
1776 bssl::ScopedEVP_HPKE_KEY key2;
1777 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1778 uint8_t *ech_config2;
1779 size_t ech_config2_len;
1780 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1781 /*config_id=*/2, key2.get(),
1782 "public.example", 16));
1783 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1784
1785 // Install both ECHConfigs in an |SSL_ECH_KEYS|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001786 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1787 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001788 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1789 ech_config_len, key.get()));
1790 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1791 ech_config2_len, key2.get()));
1792
1793 // The ECHConfigList should be correctly serialized.
1794 uint8_t *ech_config_list;
1795 size_t ech_config_list_len;
1796 ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1797 &ech_config_list_len));
1798 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1799
1800 // ECHConfigList is just the concatenation with a length prefix.
1801 size_t len = ech_config_len + ech_config2_len;
1802 std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1803 expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1804 expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1805 EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
David Benjamin24545c52021-06-07 16:05:07 -04001806}
1807
1808TEST(SSLTest, ECHHasDuplicateConfigID) {
1809 const struct {
1810 std::vector<uint8_t> ids;
1811 bool has_duplicate;
1812 } kTests[] = {
1813 {{}, false},
1814 {{1}, false},
1815 {{1, 2, 3, 255}, false},
1816 {{1, 2, 3, 1}, true},
1817 };
1818 for (const auto &test : kTests) {
1819 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1820 ASSERT_TRUE(keys);
1821 for (const uint8_t id : test.ids) {
1822 bssl::ScopedEVP_HPKE_KEY key;
1823 ASSERT_TRUE(
1824 EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1825 uint8_t *ech_config;
1826 size_t ech_config_len;
1827 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
1828 key.get(), "public.example", 16));
1829 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1830 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1831 ech_config, ech_config_len, key.get()));
1832 }
1833
1834 EXPECT_EQ(test.has_duplicate ? 1 : 0,
1835 SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
1836 }
1837}
1838
1839// Test that |SSL_ECH_KEYS_add| checks consistency between the public and
1840// private key.
1841TEST(SSLTest, ECHKeyConsistency) {
1842 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1843 ASSERT_TRUE(keys);
1844 bssl::ScopedEVP_HPKE_KEY key;
1845 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1846 uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
1847 size_t public_key_len;
1848 ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
1849 sizeof(public_key)));
1850
1851 // Adding an ECHConfig with the matching public key succeeds.
1852 ECHConfigParams params;
1853 params.key = key.get();
1854 std::vector<uint8_t> ech_config;
1855 ASSERT_TRUE(MakeECHConfig(&ech_config, params));
1856 EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1857 ech_config.data(), ech_config.size(),
1858 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001859
David Benjaminc890ae52021-06-06 13:32:29 -04001860 // Adding an ECHConfig with the wrong public key is an error.
1861 bssl::ScopedEVP_HPKE_KEY wrong_key;
1862 ASSERT_TRUE(
1863 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjamin24545c52021-06-07 16:05:07 -04001864 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1865 ech_config.data(), ech_config.size(),
1866 wrong_key.get()));
1867
1868 // Adding an ECHConfig with a truncated public key is an error.
1869 ECHConfigParams truncated;
1870 truncated.key = key.get();
1871 truncated.public_key.assign(public_key, public_key + public_key_len - 1);
1872 ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
1873 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1874 ech_config.data(), ech_config.size(), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001875
David Benjaminc890ae52021-06-06 13:32:29 -04001876 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
1877 // error.
David Benjamin24545c52021-06-07 16:05:07 -04001878 ECHConfigParams wrong_kem;
1879 wrong_kem.key = key.get();
1880 wrong_kem.kem_id = 0x0010; // DHKEM(P-256, HKDF-SHA256)
1881 ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
David Benjaminc890ae52021-06-06 13:32:29 -04001882 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1883 ech_config.data(), ech_config.size(),
1884 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001885}
1886
David Benjaminc3b373b2021-06-06 13:04:26 -04001887// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001888// has no retry configs.
1889TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
David Benjamin24545c52021-06-07 16:05:07 -04001890 bssl::ScopedEVP_HPKE_KEY key;
1891 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1892 uint8_t *ech_config;
1893 size_t ech_config_len;
1894 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1895 /*config_id=*/1, key.get(),
1896 "public.example", 16));
1897 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001898
David Benjamin24545c52021-06-07 16:05:07 -04001899 // Install a non-retry config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001900 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1901 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001902 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
1903 ech_config_len, key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001904
David Benjamin24545c52021-06-07 16:05:07 -04001905 // |keys| has no retry configs.
1906 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1907 ASSERT_TRUE(ctx);
1908 EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001909
1910 // Add the same ECHConfig to the list, but this time mark it as a retry
1911 // config.
David Benjamin24545c52021-06-07 16:05:07 -04001912 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1913 ech_config_len, key.get()));
1914 EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001915}
1916
1917// Test that the server APIs reject ECHConfigs with unsupported features.
1918TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001919 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1920 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04001921 bssl::ScopedEVP_HPKE_KEY key;
David Benjamin24545c52021-06-07 16:05:07 -04001922 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001923
1924 // Unsupported versions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001925 ECHConfigParams unsupported_version;
1926 unsupported_version.version = 0xffff;
1927 unsupported_version.key = key.get();
Daniel McArdle00e434d2021-02-18 11:47:18 -05001928 std::vector<uint8_t> ech_config;
David Benjamin24545c52021-06-07 16:05:07 -04001929 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
David Benjaminc3b373b2021-06-06 13:04:26 -04001930 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1931 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001932 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001933
David Benjamin24545c52021-06-07 16:05:07 -04001934 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1935 ECHConfigParams unsupported_kdf;
1936 unsupported_kdf.key = key.get();
1937 unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
1938 EVP_HPKE_AES_128_GCM};
1939 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
1940 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1941 ech_config.data(), ech_config.size(),
1942 key.get()));
1943 ECHConfigParams unsupported_aead;
1944 unsupported_aead.key = key.get();
1945 unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
1946 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
1947 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1948 ech_config.data(), ech_config.size(),
1949 key.get()));
1950
1951
Daniel McArdle00e434d2021-02-18 11:47:18 -05001952 // Unsupported extensions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001953 ECHConfigParams extensions;
1954 extensions.key = key.get();
1955 extensions.extensions = {0x00, 0x01, 0x00, 0x00};
1956 ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001957 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1958 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001959 key.get()));
David Benjamin9cbe7372021-06-15 18:09:10 -04001960
1961 // Invalid public names are rejected.
1962 ECHConfigParams invalid_public_name;
1963 invalid_public_name.key = key.get();
1964 invalid_public_name.public_name = "dns_names_have_no_underscores.example";
1965 ASSERT_TRUE(MakeECHConfig(&ech_config, invalid_public_name));
1966 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1967 ech_config.data(), ech_config.size(),
1968 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001969}
1970
David Benjamin83a49932021-05-20 15:57:09 -04001971// Test that |SSL_get_client_random| reports the correct value on both client
1972// and server in ECH. The client sends two different random values. When ECH is
1973// accepted, we should report the inner one.
1974TEST(SSLTest, ECHClientRandomsMatch) {
1975 bssl::UniquePtr<SSL_CTX> server_ctx =
1976 CreateContextWithTestCertificate(TLS_method());
1977 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
1978 ASSERT_TRUE(keys);
1979 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
1980
1981 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1982 ASSERT_TRUE(client_ctx);
1983 bssl::UniquePtr<SSL> client, server;
1984 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
1985 server_ctx.get()));
1986 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
1987 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
1988
1989 EXPECT_TRUE(SSL_ech_accepted(client.get()));
1990 EXPECT_TRUE(SSL_ech_accepted(server.get()));
1991
1992 // An ECH server will fairly naturally record the inner ClientHello random,
1993 // but an ECH client may forget to update the random once ClientHelloInner is
1994 // selected.
1995 uint8_t client_random1[SSL3_RANDOM_SIZE];
1996 uint8_t client_random2[SSL3_RANDOM_SIZE];
1997 ASSERT_EQ(sizeof(client_random1),
1998 SSL_get_client_random(client.get(), client_random1,
1999 sizeof(client_random1)));
2000 ASSERT_EQ(sizeof(client_random2),
2001 SSL_get_client_random(server.get(), client_random2,
2002 sizeof(client_random2)));
2003 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
2004}
2005
2006// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
2007// of the ClientHello and ECH extension, respectively, when a client created
2008// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
2009// maximum name length |max_name_len|.
2010static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
2011 size_t *out_ech_len, size_t max_name_len,
2012 const char *name) {
2013 bssl::ScopedEVP_HPKE_KEY key;
2014 uint8_t *ech_config;
2015 size_t ech_config_len;
2016 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
2017 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
2018 /*config_id=*/1, key.get(), "public.example",
2019 max_name_len)) {
2020 return false;
2021 }
2022 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2023
2024 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2025 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2026 ech_config_len, key.get())) {
2027 return false;
2028 }
2029
2030 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
2031 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
2032 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
2033 return false;
2034 }
2035 SSL_set_connect_state(ssl.get());
2036
2037 std::vector<uint8_t> client_hello;
2038 SSL_CLIENT_HELLO parsed;
2039 const uint8_t *unused;
2040 if (!GetClientHello(ssl.get(), &client_hello) ||
2041 !ssl_client_hello_init(
2042 ssl.get(), &parsed,
2043 // Skip record and handshake headers. This assumes the ClientHello
2044 // fits in one record.
2045 MakeConstSpan(client_hello)
2046 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
2047 !SSL_early_callback_ctx_extension_get(
2048 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2049 return false;
2050 }
2051 *out_client_hello_len = client_hello.size();
2052 return true;
2053}
2054
2055TEST(SSLTest, ECHPadding) {
2056 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2057 ASSERT_TRUE(ctx);
2058
2059 // Sample lengths with max_name_len = 128 as baseline.
2060 size_t client_hello_len_baseline, ech_len_baseline;
2061 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2062 &ech_len_baseline, 128, "example.com"));
2063
2064 // Check that all name lengths under the server's maximum look the same.
2065 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2066 SCOPED_TRACE(name_len);
2067 size_t client_hello_len, ech_len;
2068 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2069 std::string(name_len, 'a').c_str()));
2070 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2071 EXPECT_EQ(ech_len, ech_len_baseline);
2072 }
2073
2074 // When sending no SNI, we must still pad as if we are sending one.
2075 size_t client_hello_len, ech_len;
2076 ASSERT_TRUE(
2077 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2078 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2079 EXPECT_EQ(ech_len, ech_len_baseline);
2080
David Benjamin18b68362021-06-18 23:13:46 -04002081 // Name lengths above the maximum do not get named-based padding, but the
2082 // overall input is padded to a multiple of 32.
2083 size_t client_hello_len_baseline2, ech_len_baseline2;
2084 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline2,
2085 &ech_len_baseline2, 128,
2086 std::string(128 + 32, 'a').c_str()));
2087 EXPECT_EQ(ech_len_baseline2, ech_len_baseline + 32);
2088 // The ClientHello lengths may match if we are still under the threshold for
2089 // padding extension.
2090 EXPECT_GE(client_hello_len_baseline2, client_hello_len_baseline);
David Benjamin83a49932021-05-20 15:57:09 -04002091
David Benjamin18b68362021-06-18 23:13:46 -04002092 for (size_t name_len = 128 + 1; name_len < 128 + 32; name_len++) {
David Benjamin83a49932021-05-20 15:57:09 -04002093 SCOPED_TRACE(name_len);
2094 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2095 std::string(name_len, 'a').c_str()));
David Benjamin18b68362021-06-18 23:13:46 -04002096 EXPECT_TRUE(ech_len == ech_len_baseline || ech_len == ech_len_baseline2)
2097 << ech_len;
2098 EXPECT_TRUE(client_hello_len == client_hello_len_baseline ||
2099 client_hello_len == client_hello_len_baseline2)
2100 << client_hello_len;
David Benjamin83a49932021-05-20 15:57:09 -04002101 }
2102}
2103
David Benjamin9cbe7372021-06-15 18:09:10 -04002104TEST(SSLTest, ECHPublicName) {
2105 auto str_to_span = [](const char *str) -> Span<const uint8_t> {
2106 return MakeConstSpan(reinterpret_cast<const uint8_t *>(str), strlen(str));
2107 };
2108
2109 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("")));
2110 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("example.com")));
2111 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(".example.com")));
2112 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.com.")));
2113 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example..com")));
2114 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.-example.com")));
2115 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.example-.com")));
2116 EXPECT_FALSE(
2117 ssl_is_valid_ech_public_name(str_to_span("no_underscores.example")));
2118 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2119 str_to_span("invalid_chars.\x01.example")));
2120 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2121 str_to_span("invalid_chars.\xff.example")));
2122 static const uint8_t kWithNUL[] = {'t', 'e', 's', 't', 0};
2123 EXPECT_FALSE(ssl_is_valid_ech_public_name(kWithNUL));
2124
2125 // Test an LDH label with every character and the maximum length.
2126 EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span(
2127 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789")));
2128 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(
2129 "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-01234567899")));
2130
David Benjamin1a668b32021-09-02 23:00:28 -04002131 // Inputs with trailing numeric components are rejected.
David Benjamin9cbe7372021-06-15 18:09:10 -04002132 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.0.0.1")));
David Benjamin1a668b32021-09-02 23:00:28 -04002133 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.1")));
2134 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.01")));
2135 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0x01")));
2136 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0X01")));
2137 // Leading zeros and values that overflow |uint32_t| are still rejected.
2138 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2139 str_to_span("example.123456789000000000000000")));
2140 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2141 str_to_span("example.012345678900000000000000")));
2142 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2143 str_to_span("example.0x123456789abcdefABCDEF0")));
2144 EXPECT_FALSE(ssl_is_valid_ech_public_name(
2145 str_to_span("example.0x0123456789abcdefABCDEF")));
2146 // Adding a non-digit or non-hex character makes it a valid DNS name again.
2147 // Single-component numbers are rejected.
David Benjamin9cbe7372021-06-15 18:09:10 -04002148 EXPECT_TRUE(ssl_is_valid_ech_public_name(
David Benjamin1a668b32021-09-02 23:00:28 -04002149 str_to_span("example.1234567890a")));
2150 EXPECT_TRUE(ssl_is_valid_ech_public_name(
2151 str_to_span("example.01234567890a")));
2152 EXPECT_TRUE(ssl_is_valid_ech_public_name(
2153 str_to_span("example.0x123456789abcdefg")));
2154 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1")));
2155 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01")));
2156 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01")));
2157 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01")));
2158 // Numbers with trailing dots are rejected. (They are already rejected by the
2159 // LDH label rules, but the WHATWG URL parser additionally rejects them.)
2160 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1.")));
2161 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01.")));
2162 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01.")));
2163 EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01.")));
David Benjamin9cbe7372021-06-15 18:09:10 -04002164}
2165
David Benjaminba423c92021-06-15 16:26:58 -04002166// When using the built-in verifier, test that |SSL_get0_ech_name_override| is
2167// applied automatically.
2168TEST(SSLTest, ECHBuiltinVerifier) {
2169 // These test certificates generated with the following Go program.
2170 /* clang-format off
2171func main() {
2172 notBefore := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
2173 notAfter := time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC)
2174 rootKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2175 rootTemplate := &x509.Certificate{
2176 SerialNumber: big.NewInt(1),
2177 Subject: pkix.Name{CommonName: "Test CA"},
2178 NotBefore: notBefore,
2179 NotAfter: notAfter,
2180 BasicConstraintsValid: true,
2181 IsCA: true,
2182 }
2183 rootDER, _ := x509.CreateCertificate(rand.Reader, rootTemplate, rootTemplate, &rootKey.PublicKey, rootKey)
2184 root, _ := x509.ParseCertificate(rootDER)
2185 pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: rootDER})
2186 leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2187 leafKeyDER, _ := x509.MarshalPKCS8PrivateKey(leafKey)
2188 pem.Encode(os.Stdout, &pem.Block{Type: "PRIVATE KEY", Bytes: leafKeyDER})
2189 for i, name := range []string{"public.example", "secret.example"} {
2190 leafTemplate := &x509.Certificate{
2191 SerialNumber: big.NewInt(int64(i) + 2),
2192 Subject: pkix.Name{CommonName: name},
2193 NotBefore: notBefore,
2194 NotAfter: notAfter,
2195 BasicConstraintsValid: true,
2196 DNSNames: []string{name},
2197 }
2198 leafDER, _ := x509.CreateCertificate(rand.Reader, leafTemplate, root, &leafKey.PublicKey, rootKey)
2199 pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
2200 }
2201}
2202clang-format on */
2203 bssl::UniquePtr<X509> root = CertFromPEM(R"(
2204-----BEGIN CERTIFICATE-----
2205MIIBRzCB7aADAgECAgEBMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMTB1Rlc3QgQ0Ew
2206IBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMBIxEDAOBgNVBAMTB1Rl
2207c3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT5JUjrI1DAxSpEl88UkmJw
2208tAJqxo/YrSFo9V3MkcNkfTixi5p6MUtO8DazhEgekBcd2+tBAWtl7dy0qpvTqx92
2209ozIwMDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTw6ftkexAI6o4r5FntJIfL
2210GU5F4zAKBggqhkjOPQQDAgNJADBGAiEAiiNowddQeHZaZFIygwe6RW5/WG4sUXWC
2211dkyl9CQzRaYCIQCFS1EvwZbZtMny27fYm1eeYciY0TkJTEi34H1KwyzzIA==
2212-----END CERTIFICATE-----
2213)");
2214 ASSERT_TRUE(root);
2215 bssl::UniquePtr<EVP_PKEY> leaf_key = KeyFromPEM(R"(
2216-----BEGIN PRIVATE KEY-----
2217MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgj5WKHwHnziiyPauf
22187QukxTwtTyGZkk8qNdms4puJfxqhRANCAARNrkhxabALDlJrHtvkuDwvCWUF/oVC
2219hr6PDITHi1lDlJzvVT4aXBH87sH2n2UV5zpx13NHkq1bIC8eRT8eOIe0
2220-----END PRIVATE KEY-----
2221)");
2222 ASSERT_TRUE(leaf_key);
2223 bssl::UniquePtr<X509> leaf_public = CertFromPEM(R"(
2224-----BEGIN CERTIFICATE-----
2225MIIBaDCCAQ6gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2226MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5w
2227dWJsaWMuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2228Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2229Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2230K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOcHVibGljLmV4YW1wbGUwCgYIKoZIzj0E
2231AwIDSAAwRQIhANqZRhDR/+QL05hsWXMYEwaiHifd9iakKoFEhKFchcF3AiBRAeXw
2232wRGGT6+iPmTYM6N5/IDyAb5B9Ke38O6lLEsUwA==
2233-----END CERTIFICATE-----
2234)");
2235 ASSERT_TRUE(leaf_public);
2236 bssl::UniquePtr<X509> leaf_secret = CertFromPEM(R"(
2237-----BEGIN CERTIFICATE-----
2238MIIBaTCCAQ6gAwIBAgIBAzAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2239MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5z
2240ZWNyZXQuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2241Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2242Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2243K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOc2VjcmV0LmV4YW1wbGUwCgYIKoZIzj0E
2244AwIDSQAwRgIhAPQdIz1xCFkc9WuSkxOxJDpywZiEp9SnKcxJ9nwrlRp3AiEA+O3+
2245XRqE7XFhHL+7TNC2a9OOAjQsEF137YPWo+rhgko=
2246-----END CERTIFICATE-----
2247)");
2248 ASSERT_TRUE(leaf_secret);
2249
2250 // Use different config IDs so that fuzzer mode, which breaks trial
2251 // decryption, will observe the key mismatch.
2252 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys(/*config_id=*/1);
2253 ASSERT_TRUE(keys);
2254 bssl::UniquePtr<SSL_ECH_KEYS> wrong_keys = MakeTestECHKeys(/*config_id=*/2);
2255 ASSERT_TRUE(wrong_keys);
2256 bssl::UniquePtr<SSL_CTX> server_ctx =
2257 CreateContextWithTestCertificate(TLS_method());
2258 ASSERT_TRUE(server_ctx);
2259 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2260 ASSERT_TRUE(client_ctx);
2261
2262 // Configure the client to verify certificates and expect the secret name.
2263 // This is the name the client is trying to connect to. If ECH is rejected,
2264 // BoringSSL will internally override this setting with the public name.
2265 bssl::UniquePtr<X509_STORE> store(X509_STORE_new());
2266 ASSERT_TRUE(store);
2267 ASSERT_TRUE(X509_STORE_add_cert(store.get(), root.get()));
2268 SSL_CTX_set_cert_store(client_ctx.get(), store.release());
2269 SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER, nullptr);
2270 static const char kSecretName[] = "secret.example";
2271 ASSERT_TRUE(X509_VERIFY_PARAM_set1_host(SSL_CTX_get0_param(client_ctx.get()),
2272 kSecretName, strlen(kSecretName)));
2273
2274 // For simplicity, we only run through a pair of representative scenarios here
2275 // and rely on runner.go to verify that |SSL_get0_ech_name_override| behaves
2276 // correctly.
2277 for (bool accept_ech : {false, true}) {
2278 SCOPED_TRACE(accept_ech);
2279 for (bool use_leaf_secret : {false, true}) {
2280 SCOPED_TRACE(use_leaf_secret);
2281
2282 // The server will reject ECH when configured with the wrong keys.
2283 ASSERT_TRUE(SSL_CTX_set1_ech_keys(
2284 server_ctx.get(), accept_ech ? keys.get() : wrong_keys.get()));
2285
2286 bssl::UniquePtr<SSL> client, server;
2287 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2288 server_ctx.get()));
2289 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
2290
2291 // Configure the server with the selected certificate.
2292 ASSERT_TRUE(SSL_use_certificate(server.get(), use_leaf_secret
2293 ? leaf_secret.get()
2294 : leaf_public.get()));
2295 ASSERT_TRUE(SSL_use_PrivateKey(server.get(), leaf_key.get()));
2296
2297 // The handshake may fail due to name mismatch or ECH reject. We check
2298 // |SSL_get_verify_result| to confirm the handshake got far enough.
2299 CompleteHandshakes(client.get(), server.get());
2300 EXPECT_EQ(accept_ech == use_leaf_secret ? X509_V_OK
2301 : X509_V_ERR_HOSTNAME_MISMATCH,
2302 SSL_get_verify_result(client.get()));
2303 }
2304 }
2305}
2306
David Benjamin83a49932021-05-20 15:57:09 -04002307#if defined(OPENSSL_THREADS)
2308// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2309// in use on other threads. This test is intended to be run with TSan.
2310TEST(SSLTest, ECHThreads) {
2311 // Generate a pair of ECHConfigs.
2312 bssl::ScopedEVP_HPKE_KEY key1;
2313 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2314 uint8_t *ech_config1;
2315 size_t ech_config1_len;
2316 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2317 /*config_id=*/1, key1.get(),
2318 "public.example", 16));
2319 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2320 bssl::ScopedEVP_HPKE_KEY key2;
2321 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2322 uint8_t *ech_config2;
2323 size_t ech_config2_len;
2324 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2325 /*config_id=*/2, key2.get(),
2326 "public.example", 16));
2327 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2328
2329 // |keys1| contains the first config. |keys12| contains both.
2330 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2331 ASSERT_TRUE(keys1);
2332 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2333 ech_config1_len, key1.get()));
2334 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2335 ASSERT_TRUE(keys12);
2336 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2337 ech_config2_len, key2.get()));
2338 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2339 ech_config1_len, key1.get()));
2340
2341 bssl::UniquePtr<SSL_CTX> server_ctx =
2342 CreateContextWithTestCertificate(TLS_method());
2343 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2344
2345 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2346 ASSERT_TRUE(client_ctx);
2347 bssl::UniquePtr<SSL> client, server;
2348 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2349 server_ctx.get()));
2350 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2351
2352 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2353 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2354 // the same whichever the server uses.
2355 std::vector<std::thread> threads;
2356 threads.emplace_back([&] {
2357 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2358 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2359 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2360 });
2361 threads.emplace_back([&] {
2362 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2363 });
2364 for (auto &thread : threads) {
2365 thread.join();
2366 }
2367}
2368#endif // OPENSSL_THREADS
2369
David Benjaminc79ae7a2017-08-29 16:09:44 -04002370static void AppendSession(SSL_SESSION *session, void *arg) {
2371 std::vector<SSL_SESSION*> *out =
2372 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2373 out->push_back(session);
2374}
2375
2376// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2377// order.
2378static bool CacheEquals(SSL_CTX *ctx,
2379 const std::vector<SSL_SESSION*> &expected) {
2380 // Check the linked list.
2381 SSL_SESSION *ptr = ctx->session_cache_head;
2382 for (SSL_SESSION *session : expected) {
2383 if (ptr != session) {
2384 return false;
2385 }
2386 // TODO(davidben): This is an absurd way to denote the end of the list.
2387 if (ptr->next ==
2388 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2389 ptr = nullptr;
2390 } else {
2391 ptr = ptr->next;
2392 }
2393 }
2394 if (ptr != nullptr) {
2395 return false;
2396 }
2397
2398 // Check the hash table.
2399 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002400 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002401 expected_copy = expected;
2402
2403 std::sort(actual.begin(), actual.end());
2404 std::sort(expected_copy.begin(), expected_copy.end());
2405
2406 return actual == expected_copy;
2407}
2408
2409static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2410 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2411 if (!ssl_ctx) {
2412 return nullptr;
2413 }
2414 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2415 if (!ret) {
2416 return nullptr;
2417 }
2418
David Benjaminaaef8332018-06-29 16:45:49 -04002419 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2420 OPENSSL_memcpy(id, &number, sizeof(number));
2421 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2422 return nullptr;
2423 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002424 return ret;
2425}
2426
2427// Test that the internal session cache behaves as expected.
2428TEST(SSLTest, InternalSessionCache) {
2429 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2430 ASSERT_TRUE(ctx);
2431
2432 // Prepare 10 test sessions.
2433 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2434 for (int i = 0; i < 10; i++) {
2435 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2436 ASSERT_TRUE(session);
2437 sessions.push_back(std::move(session));
2438 }
2439
2440 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2441
2442 // Insert all the test sessions.
2443 for (const auto &session : sessions) {
2444 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2445 }
2446
2447 // Only the last five should be in the list.
2448 ASSERT_TRUE(CacheEquals(
2449 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2450 sessions[6].get(), sessions[5].get()}));
2451
2452 // Inserting an element already in the cache should fail and leave the cache
2453 // unchanged.
2454 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2455 ASSERT_TRUE(CacheEquals(
2456 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2457 sessions[6].get(), sessions[5].get()}));
2458
2459 // Although collisions should be impossible (256-bit session IDs), the cache
2460 // must handle them gracefully.
2461 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2462 ASSERT_TRUE(collision);
2463 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2464 ASSERT_TRUE(CacheEquals(
2465 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2466 sessions[6].get(), sessions[5].get()}));
2467
2468 // Removing sessions behaves correctly.
2469 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2470 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2471 sessions[8].get(), sessions[5].get()}));
2472
2473 // Removing sessions requires an exact match.
2474 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2475 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2476
2477 // The cache remains unchanged.
2478 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2479 sessions[8].get(), sessions[5].get()}));
2480}
2481
2482static uint16_t EpochFromSequence(uint64_t seq) {
2483 return static_cast<uint16_t>(seq >> 48);
2484}
2485
David Benjamin71dfad42017-07-16 17:27:39 -04002486static const uint8_t kTestName[] = {
2487 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2488 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2489 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2490 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2491 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2492 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2493};
2494
David Benjaminc11ea9422017-08-29 16:33:21 -04002495// SSLVersionTest executes its test cases under all available protocol versions.
2496// Test cases call |Connect| to create a connection using context objects with
2497// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002498class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2499 protected:
2500 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2501
2502 void SetUp() { ResetContexts(); }
2503
2504 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2505 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2506 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2507 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2508 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2509 return nullptr;
2510 }
2511 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002512 }
David Benjamin686bb192016-05-10 15:15:41 -04002513
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002514 void ResetContexts() {
2515 ASSERT_TRUE(cert_);
2516 ASSERT_TRUE(key_);
2517 client_ctx_ = CreateContext();
2518 ASSERT_TRUE(client_ctx_);
2519 server_ctx_ = CreateContext();
2520 ASSERT_TRUE(server_ctx_);
2521 // Set up a server cert. Client certs can be set up explicitly.
2522 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002523 }
David Benjamin686bb192016-05-10 15:15:41 -04002524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 bool UseCertAndKey(SSL_CTX *ctx) const {
2526 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2527 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002528 }
David Benjamin686bb192016-05-10 15:15:41 -04002529
David Benjamina8614602017-09-06 15:40:19 -04002530 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002531 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002532 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002533 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002534 }
2535
2536 uint16_t version() const { return GetParam().version; }
2537
2538 bool is_dtls() const {
2539 return GetParam().ssl_method == VersionParam::is_dtls;
2540 }
2541
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002542 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002543 bssl::UniquePtr<SSL> client_, server_;
2544 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2545 bssl::UniquePtr<X509> cert_;
2546 bssl::UniquePtr<EVP_PKEY> key_;
2547};
2548
David Benjaminbe7006a2019-04-09 18:05:02 -05002549INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2550 testing::ValuesIn(kAllVersions),
2551 [](const testing::TestParamInfo<VersionParam> &i) {
2552 return i.param.name;
2553 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002554
2555TEST_P(SSLVersionTest, SequenceNumber) {
2556 ASSERT_TRUE(Connect());
2557
David Benjamin0fef3052016-11-18 15:11:10 +09002558 // Drain any post-handshake messages to ensure there are no unread records
2559 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002560 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002561
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002562 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2563 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2564 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2565 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002566
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002567 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002568 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002569 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2570 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2571 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2572 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002573
2574 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002575 EXPECT_GT(client_write_seq, server_read_seq);
2576 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002577 } else {
2578 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002579 EXPECT_EQ(client_write_seq, server_read_seq);
2580 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002581 }
2582
2583 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002584 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002585 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2586 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002587
2588 // The client write and server read sequence numbers should have
2589 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002590 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2591 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002592}
2593
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002594TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002595 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002596 if (is_dtls()) {
2597 return;
David Benjamin686bb192016-05-10 15:15:41 -04002598 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002599 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002600
David Benjamin9734e442021-06-15 13:58:12 -04002601 // Shut down half the connection. |SSL_shutdown| will return 0 to signal only
David Benjamin686bb192016-05-10 15:15:41 -04002602 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002603 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002604
2605 // Reading from the server should consume the EOF.
2606 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002607 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2608 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002609
2610 // However, the server may continue to write data and then shut down the
2611 // connection.
2612 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002613 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2614 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2615 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002616
2617 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002618 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2619 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002620}
David Benjamin68f37b72016-11-18 15:14:42 +09002621
David Benjamin9734e442021-06-15 13:58:12 -04002622// Test that, after calling |SSL_shutdown|, |SSL_write| fails.
2623TEST_P(SSLVersionTest, WriteAfterShutdown) {
2624 ASSERT_TRUE(Connect());
2625
2626 for (SSL *ssl : {client_.get(), server_.get()}) {
2627 SCOPED_TRACE(SSL_is_server(ssl) ? "server" : "client");
2628
2629 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2630 ASSERT_TRUE(mem);
2631 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2632
2633 // Shut down half the connection. |SSL_shutdown| will return 0 to signal
2634 // only one side has shut down.
2635 ASSERT_EQ(SSL_shutdown(ssl), 0);
2636
2637 // |ssl| should have written an alert to the transport.
2638 const uint8_t *unused;
2639 size_t len;
2640 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2641 EXPECT_NE(0u, len);
2642 EXPECT_TRUE(BIO_reset(mem.get()));
2643
2644 // Writing should fail.
2645 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2646
2647 // Nothing should be written to the transport.
2648 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2649 EXPECT_EQ(0u, len);
2650 }
2651}
2652
2653// Test that, after sending a fatal alert in a failed |SSL_read|, |SSL_write|
2654// fails.
2655TEST_P(SSLVersionTest, WriteAfterReadSentFatalAlert) {
2656 // Decryption failures are not fatal in DTLS.
2657 if (is_dtls()) {
2658 return;
2659 }
2660
2661 ASSERT_TRUE(Connect());
2662
2663 // Save the write |BIO|s as the test will overwrite them.
2664 bssl::UniquePtr<BIO> client_wbio = bssl::UpRef(SSL_get_wbio(client_.get()));
2665 bssl::UniquePtr<BIO> server_wbio = bssl::UpRef(SSL_get_wbio(server_.get()));
2666
2667 for (bool test_server : {false, true}) {
2668 SCOPED_TRACE(test_server ? "server" : "client");
2669 SSL *ssl = test_server ? server_.get() : client_.get();
2670 BIO *other_wbio = test_server ? client_wbio.get() : server_wbio.get();
2671
2672 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2673 ASSERT_TRUE(mem);
2674 SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2675
2676 // Read an invalid record from the peer.
2677 static const uint8_t kInvalidRecord[] = "invalid record";
2678 EXPECT_EQ(int{sizeof(kInvalidRecord)},
2679 BIO_write(other_wbio, kInvalidRecord, sizeof(kInvalidRecord)));
2680 char buf[256];
2681 EXPECT_EQ(-1, SSL_read(ssl, buf, sizeof(buf)));
2682
2683 // |ssl| should have written an alert to the transport.
2684 const uint8_t *unused;
2685 size_t len;
2686 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2687 EXPECT_NE(0u, len);
2688 EXPECT_TRUE(BIO_reset(mem.get()));
2689
2690 // Writing should fail.
2691 EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2692
2693 // Nothing should be written to the transport.
2694 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2695 EXPECT_EQ(0u, len);
2696 }
2697}
2698
2699// Test that, after sending a fatal alert from the handshake, |SSL_write| fails.
2700TEST_P(SSLVersionTest, WriteAfterHandshakeSentFatalAlert) {
2701 for (bool test_server : {false, true}) {
2702 SCOPED_TRACE(test_server ? "server" : "client");
2703
2704 bssl::UniquePtr<SSL> ssl(
2705 SSL_new(test_server ? server_ctx_.get() : client_ctx_.get()));
2706 ASSERT_TRUE(ssl);
2707 if (test_server) {
2708 SSL_set_accept_state(ssl.get());
2709 } else {
2710 SSL_set_connect_state(ssl.get());
2711 }
2712
2713 std::vector<uint8_t> invalid;
2714 if (is_dtls()) {
2715 // In DTLS, invalid records are discarded. To cause the handshake to fail,
2716 // use a valid handshake record with invalid contents.
2717 invalid.push_back(SSL3_RT_HANDSHAKE);
2718 invalid.push_back(DTLS1_VERSION >> 8);
2719 invalid.push_back(DTLS1_VERSION & 0xff);
2720 // epoch and sequence_number
2721 for (int i = 0; i < 8; i++) {
2722 invalid.push_back(0);
2723 }
2724 // A one-byte fragment is invalid.
2725 invalid.push_back(0);
2726 invalid.push_back(1);
2727 // Arbitrary contents.
2728 invalid.push_back(0);
2729 } else {
2730 invalid = {'i', 'n', 'v', 'a', 'l', 'i', 'd'};
2731 }
2732 bssl::UniquePtr<BIO> rbio(
2733 BIO_new_mem_buf(invalid.data(), invalid.size()));
2734 ASSERT_TRUE(rbio);
2735 SSL_set0_rbio(ssl.get(), rbio.release());
2736
2737 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2738 ASSERT_TRUE(mem);
2739 SSL_set0_wbio(ssl.get(), bssl::UpRef(mem).release());
2740
2741 // The handshake should fail.
2742 EXPECT_EQ(-1, SSL_do_handshake(ssl.get()));
2743 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2744 uint32_t err = ERR_get_error();
2745
2746 // |ssl| should have written an alert (and, in the client's case, a
2747 // ClientHello) to the transport.
2748 const uint8_t *unused;
2749 size_t len;
2750 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2751 EXPECT_NE(0u, len);
2752 EXPECT_TRUE(BIO_reset(mem.get()));
2753
2754 // Writing should fail, with the same error as the handshake.
2755 EXPECT_EQ(-1, SSL_write(ssl.get(), "a", 1));
2756 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2757 EXPECT_EQ(err, ERR_get_error());
2758
2759 // Nothing should be written to the transport.
2760 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2761 EXPECT_EQ(0u, len);
2762 }
2763}
2764
2765// Test that, after seeing TLS 1.2 in response to early data, |SSL_write|
2766// continues to report |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. See
2767// https://crbug.com/1078515.
2768TEST(SSLTest, WriteAfterWrongVersionOnEarlyData) {
2769 // Set up some 0-RTT-enabled contexts.
2770 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2771 bssl::UniquePtr<SSL_CTX> server_ctx =
2772 CreateContextWithTestCertificate(TLS_method());
2773 ASSERT_TRUE(client_ctx);
2774 ASSERT_TRUE(server_ctx);
2775 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
2776 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
2777 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2778 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2779
2780 // Get an early-data-capable session.
2781 bssl::UniquePtr<SSL_SESSION> session =
2782 CreateClientSession(client_ctx.get(), server_ctx.get());
2783 ASSERT_TRUE(session);
2784 EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
2785
2786 // Offer the session to the server, but now the server speaks TLS 1.2.
2787 bssl::UniquePtr<SSL> client, server;
2788 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2789 server_ctx.get()));
2790 SSL_set_session(client.get(), session.get());
2791 EXPECT_TRUE(SSL_set_max_proto_version(server.get(), TLS1_2_VERSION));
2792
2793 // The client handshake initially succeeds in the early data state.
2794 EXPECT_EQ(1, SSL_do_handshake(client.get()));
2795 EXPECT_TRUE(SSL_in_early_data(client.get()));
2796
2797 // The server processes the ClientHello and negotiates TLS 1.2.
2798 EXPECT_EQ(-1, SSL_do_handshake(server.get()));
2799 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server.get(), -1));
2800 EXPECT_EQ(TLS1_2_VERSION, SSL_version(server.get()));
2801
2802 // Capture the client's output.
2803 bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2804 ASSERT_TRUE(mem);
2805 SSL_set0_wbio(client.get(), bssl::UpRef(mem).release());
2806
2807 // The client processes the ServerHello and fails.
2808 EXPECT_EQ(-1, SSL_do_handshake(client.get()));
2809 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2810 uint32_t err = ERR_get_error();
2811 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2812 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2813
2814 // The client should have written an alert to the transport.
2815 const uint8_t *unused;
2816 size_t len;
2817 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2818 EXPECT_NE(0u, len);
2819 EXPECT_TRUE(BIO_reset(mem.get()));
2820
2821 // Writing should fail, with the same error as the handshake.
2822 EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
2823 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
2824 err = ERR_get_error();
2825 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
2826 EXPECT_EQ(SSL_R_WRONG_VERSION_ON_EARLY_DATA, ERR_GET_REASON(err));
2827
2828 // Nothing should be written to the transport.
2829 ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2830 EXPECT_EQ(0u, len);
2831}
2832
David Benjaminf0d8e222017-02-04 10:58:26 -05002833TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002834 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002835 bssl::UniquePtr<SSL_CTX> server_ctx =
2836 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002837 ASSERT_TRUE(client_ctx);
2838 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002839
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002840 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002841 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002842 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002843
2844 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002845 bssl::UniquePtr<SSL_SESSION> session1 =
2846 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002847 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002848
David Benjamina3a71e92018-06-29 13:24:45 -04002849 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002850
Steven Valdez87eab492016-06-27 16:34:59 -04002851 uint8_t *s0_bytes, *s1_bytes;
2852 size_t s0_len, s1_len;
2853
David Benjaminf0d8e222017-02-04 10:58:26 -05002854 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002855 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002856
David Benjaminf0d8e222017-02-04 10:58:26 -05002857 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002858 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002859
David Benjamin7d7554b2017-02-04 11:48:59 -05002860 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002861}
David Benjamin686bb192016-05-10 15:15:41 -04002862
David Benjaminf0d8e222017-02-04 10:58:26 -05002863static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002864 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002865 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2866 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002867
2868 // The wrapper BIOs are always equal when fds are equal, even if set
2869 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002870 if (rfd == wfd) {
2871 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002872 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002873}
2874
David Benjaminf0d8e222017-02-04 10:58:26 -05002875TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002876 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002877 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002878
2879 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002880 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002881 ASSERT_TRUE(ssl);
2882 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2883 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2884 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002885
2886 // Test setting the same FD.
2887 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002888 ASSERT_TRUE(ssl);
2889 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2890 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002891
2892 // Test setting the same FD one side at a time.
2893 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002894 ASSERT_TRUE(ssl);
2895 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2896 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2897 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002898
2899 // Test setting the same FD in the other order.
2900 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002901 ASSERT_TRUE(ssl);
2902 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2903 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2904 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002905
David Benjamin5c0fb882016-06-14 14:03:51 -04002906 // Test changing the read FD partway through.
2907 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002908 ASSERT_TRUE(ssl);
2909 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2910 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2911 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002912
2913 // Test changing the write FD partway through.
2914 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002915 ASSERT_TRUE(ssl);
2916 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2917 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2918 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002919
2920 // Test a no-op change to the read FD partway through.
2921 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002922 ASSERT_TRUE(ssl);
2923 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2924 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2925 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002926
2927 // Test a no-op change to the write FD partway through.
2928 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002929 ASSERT_TRUE(ssl);
2930 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2931 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2932 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002933
2934 // ASan builds will implicitly test that the internal |BIO| reference-counting
2935 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002936}
2937
David Benjaminf0d8e222017-02-04 10:58:26 -05002938TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002939 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002940 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002941
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002942 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2943 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002944 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002945 ASSERT_TRUE(ssl);
2946 ASSERT_TRUE(bio1);
2947 ASSERT_TRUE(bio2);
2948 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002949
2950 // SSL_set_bio takes one reference when the parameters are the same.
2951 BIO_up_ref(bio1.get());
2952 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2953
2954 // Repeating the call does nothing.
2955 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2956
2957 // It takes one reference each when the parameters are different.
2958 BIO_up_ref(bio2.get());
2959 BIO_up_ref(bio3.get());
2960 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2961
2962 // Repeating the call does nothing.
2963 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2964
2965 // It takes one reference when changing only wbio.
2966 BIO_up_ref(bio1.get());
2967 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2968
2969 // It takes one reference when changing only rbio and the two are different.
2970 BIO_up_ref(bio3.get());
2971 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2972
2973 // If setting wbio to rbio, it takes no additional references.
2974 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2975
2976 // From there, wbio may be switched to something else.
2977 BIO_up_ref(bio1.get());
2978 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2979
2980 // If setting rbio to wbio, it takes no additional references.
2981 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2982
2983 // From there, rbio may be switched to something else, but, for historical
2984 // reasons, it takes a reference to both parameters.
2985 BIO_up_ref(bio1.get());
2986 BIO_up_ref(bio2.get());
2987 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2988
2989 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2990 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002991}
2992
David Benjamin25490f22016-07-14 00:22:54 -04002993static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2994
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002995TEST_P(SSLVersionTest, GetPeerCertificate) {
2996 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002997
David Benjamin0fef3052016-11-18 15:11:10 +09002998 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002999 SSL_CTX_set_verify(client_ctx_.get(),
3000 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3001 nullptr);
3002 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3003 SSL_CTX_set_verify(server_ctx_.get(),
3004 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3005 nullptr);
3006 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04003007
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003008 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04003009
David Benjamin0fef3052016-11-18 15:11:10 +09003010 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003011 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3012 ASSERT_TRUE(peer);
3013 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04003014
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003015 peer.reset(SSL_get_peer_certificate(client_.get()));
3016 ASSERT_TRUE(peer);
3017 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04003018
David Benjamine664a532017-07-20 20:19:36 -04003019 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09003020 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003021 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
3022 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
3023 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04003024
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003025 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
3026 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
3027 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04003028}
3029
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003030TEST_P(SSLVersionTest, NoPeerCertificate) {
3031 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
3032 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3033 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04003034
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003035 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04003036
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003037 // Server should not see a peer certificate.
3038 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3039 ASSERT_FALSE(peer);
3040 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04003041}
3042
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003043TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04003044 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003045 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
3046 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003047 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04003048
3049 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
3050 SHA256(cert_der, cert_der_len, cert_sha256);
3051
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003052 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3053
David Benjamin0fef3052016-11-18 15:11:10 +09003054 // Configure both client and server to accept any certificate, but the
3055 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003056 SSL_CTX_set_verify(client_ctx_.get(),
3057 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3058 nullptr);
3059 SSL_CTX_set_verify(server_ctx_.get(),
3060 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3061 nullptr);
3062 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3063 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3064 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04003065
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003066 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04003067
David Benjamin0fef3052016-11-18 15:11:10 +09003068 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003069 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3070 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04003071
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003072 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04003073 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04003074
David Benjamin02de7bd2018-05-08 18:13:54 -04003075 const uint8_t *peer_sha256;
3076 size_t peer_sha256_len;
3077 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
3078 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04003079}
3080
David Benjamin737d2df2017-09-25 15:05:19 -04003081// Tests that our ClientHellos do not change unexpectedly. These are purely
3082// change detection tests. If they fail as part of an intentional ClientHello
3083// change, update the test vector.
3084TEST(SSLTest, ClientHello) {
3085 struct {
3086 uint16_t max_version;
3087 std::vector<uint8_t> expected;
3088 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04003089 {TLS1_VERSION,
3090 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
3091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
3094 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07003095 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
3096 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
3097 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04003098 {TLS1_1_VERSION,
3099 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
3100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
3103 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07003104 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
3105 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
3106 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04003107 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04003108 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04003109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04003111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04003112 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04003113 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07003114 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
3115 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
3116 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
3117 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
3118 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
3119 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04003120 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
3121 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02003122 };
David Benjamin737d2df2017-09-25 15:05:19 -04003123
3124 for (const auto &t : kTests) {
3125 SCOPED_TRACE(t.max_version);
3126
3127 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3128 ASSERT_TRUE(ctx);
3129 // Our default cipher list varies by CPU capabilities, so manually place the
3130 // ChaCha20 ciphers in front.
3131 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04003132 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
3133 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
3134
3135 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3136 ASSERT_TRUE(ssl);
3137 std::vector<uint8_t> client_hello;
3138 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
3139
3140 // Zero the client_random.
3141 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
3142 1 + 3 + // handshake message header
3143 2; // client_version
3144 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
3145 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
3146
3147 if (client_hello != t.expected) {
3148 ADD_FAILURE() << "ClientHellos did not match.";
3149 // Print the value manually so it is easier to update the test vector.
3150 for (size_t i = 0; i < client_hello.size(); i += 12) {
3151 printf(" %c", i == 0 ? '{' : ' ');
3152 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
3153 if (j > i) {
3154 printf(" ");
3155 }
3156 printf("0x%02x", client_hello[j]);
3157 if (j < client_hello.size() - 1) {
3158 printf(",");
3159 }
3160 }
3161 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07003162 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04003163 }
3164 printf("\n");
3165 }
3166 }
David Benjaminafc64de2016-07-19 17:12:41 +02003167 }
David Benjaminafc64de2016-07-19 17:12:41 +02003168}
3169
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003170static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
3171 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003172 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003173 ClientConfig config;
3174 config.session = session;
3175 EXPECT_TRUE(
3176 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04003177
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003178 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04003179
3180 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003181 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04003182}
3183
David Benjamin3c51d9b2016-11-01 17:50:42 -04003184static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
3185 SSL_CTX *server_ctx,
3186 SSL_SESSION *session) {
3187 g_last_session = nullptr;
3188 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
3189
3190 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04003191 ClientConfig config;
3192 config.session = session;
3193 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05003194 config) ||
3195 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003196 fprintf(stderr, "Failed to connect client and server.\n");
3197 return nullptr;
3198 }
3199
3200 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
3201 fprintf(stderr, "Client and server were inconsistent.\n");
3202 return nullptr;
3203 }
3204
3205 if (!SSL_session_reused(client.get())) {
3206 fprintf(stderr, "Session was not reused.\n");
3207 return nullptr;
3208 }
3209
David Benjamin3c51d9b2016-11-01 17:50:42 -04003210 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
3211
3212 if (!g_last_session) {
3213 fprintf(stderr, "Client did not receive a renewed session.\n");
3214 return nullptr;
3215 }
3216 return std::move(g_last_session);
3217}
3218
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003219static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003220 bool changed) {
3221 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04003222 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003223 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
3224 if (changed) {
3225 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3226 } else {
3227 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003228 }
3229 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003230}
3231
David Benjamina933c382016-10-28 00:10:03 -04003232static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
3233 static const uint8_t kContext[] = {3};
3234
3235 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
3236 return SSL_TLSEXT_ERR_ALERT_FATAL;
3237 }
3238
3239 return SSL_TLSEXT_ERR_OK;
3240}
3241
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003242TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04003243 static const uint8_t kContext1[] = {1};
3244 static const uint8_t kContext2[] = {2};
3245
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003246 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3247 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04003248
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003249 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3250 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04003251
David Benjamin0fef3052016-11-18 15:11:10 +09003252 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003253 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3254 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04003255
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003256 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3257 session.get(),
3258 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003259
David Benjamin0fef3052016-11-18 15:11:10 +09003260 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003261 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
3262 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04003263
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003264 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3265 session.get(),
3266 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003267
David Benjamin0fef3052016-11-18 15:11:10 +09003268 // Change the session ID context back and install an SNI callback to switch
3269 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003270 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3271 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04003272
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003273 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003274 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04003275
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003276 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3277 session.get(),
3278 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04003279
David Benjamin0fef3052016-11-18 15:11:10 +09003280 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003281 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003282 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003283 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003284 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3285 static const uint8_t kContext[] = {3};
3286
3287 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
3288 sizeof(kContext))) {
3289 return ssl_select_cert_error;
3290 }
3291
3292 return ssl_select_cert_success;
3293 });
David Benjamina933c382016-10-28 00:10:03 -04003294
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003295 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3296 session.get(),
3297 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04003298}
3299
David Benjamin721e8b72016-08-03 13:13:17 -04003300static timeval g_current_time;
3301
3302static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
3303 *out_clock = g_current_time;
3304}
3305
David Benjamin17b30832017-01-28 14:00:32 -05003306static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
3307 out_clock->tv_sec = 1000;
3308 out_clock->tv_usec = 0;
3309}
3310
David Benjamin3c51d9b2016-11-01 17:50:42 -04003311static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
3312 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
3313 int encrypt) {
3314 static const uint8_t kZeros[16] = {0};
3315
3316 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05003317 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04003318 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05003319 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04003320 return 0;
3321 }
3322
3323 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
3324 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
3325 return -1;
3326 }
3327
3328 // Returning two from the callback in decrypt mode renews the
3329 // session in TLS 1.2 and below.
3330 return encrypt ? 1 : 2;
3331}
3332
David Benjamin123db572016-11-03 16:59:25 -04003333static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04003334 const uint8_t *ticket;
3335 size_t ticket_len;
3336 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
3337 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04003338 return false;
3339 }
3340
David Benjaminaaef8332018-06-29 16:45:49 -04003341 const uint8_t *ciphertext = ticket + 16 + 16;
3342 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04003343 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
3344
David Benjamin9b63f292016-11-15 00:44:05 -05003345#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3346 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05003347 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05003348#else
3349 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04003350 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04003351 bssl::ScopedEVP_CIPHER_CTX ctx;
3352 int len1, len2;
3353 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
3354 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
3355 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
3356 return false;
3357 }
3358
3359 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05003360#endif
David Benjamin123db572016-11-03 16:59:25 -04003361
Adam Langley46db7af2017-02-01 15:49:37 -08003362 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
3363 if (!ssl_ctx) {
3364 return false;
3365 }
David Benjamin123db572016-11-03 16:59:25 -04003366 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08003367 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04003368 if (!server_session) {
3369 return false;
3370 }
3371
David Benjaminaaef8332018-06-29 16:45:49 -04003372 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04003373 return true;
3374}
3375
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003376TEST_P(SSLVersionTest, SessionTimeout) {
3377 for (bool server_test : {false, true}) {
3378 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04003379
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003380 ResetContexts();
3381 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3382 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3383
David Benjamin17b30832017-01-28 14:00:32 -05003384 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09003385 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04003386
David Benjamin17b30832017-01-28 14:00:32 -05003387 // We are willing to use a longer lifetime for TLS 1.3 sessions as
3388 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003389 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05003390 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
3391 : SSL_DEFAULT_SESSION_TIMEOUT;
3392
David Benjamin17b30832017-01-28 14:00:32 -05003393 // Both client and server must enforce session timeouts. We configure the
3394 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09003395 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003396 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3397 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003398 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003399 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
3400 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003401 }
3402
3403 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003404 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09003405
3406 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003407 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3408 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09003409
3410 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05003411 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09003412
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003413 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3414 session.get(),
3415 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003416
3417 // Advance the clock one more second.
3418 g_current_time.tv_sec++;
3419
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003420 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3421 session.get(),
3422 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003423
3424 // Rewind the clock to before the session was minted.
3425 g_current_time.tv_sec = kStartTime - 1;
3426
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003427 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3428 session.get(),
3429 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09003430
David Benjamin0fef3052016-11-18 15:11:10 +09003431 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05003432 time_t new_start_time = kStartTime + timeout - 10;
3433 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003434 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
3435 client_ctx_.get(), server_ctx_.get(), session.get());
3436 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09003437
3438 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003439 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003440
3441 // Check the sessions have timestamps measured from issuance.
3442 long session_time = 0;
3443 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003444 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003445 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003446 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003447 }
David Benjamin721e8b72016-08-03 13:13:17 -04003448
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003449 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003450
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003451 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003452 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3453 // lifetime TLS 1.3.
3454 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003455 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3456 new_session.get(),
3457 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003458
David Benjamin17b30832017-01-28 14:00:32 -05003459 // The new session expires after the new timeout.
3460 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003461 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3462 new_session.get(),
3463 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003464
3465 // Renew the session until it begins just past the auth timeout.
3466 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3467 while (new_start_time < auth_end_time - 1000) {
3468 // Get as close as possible to target start time.
3469 new_start_time =
3470 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3471 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003472 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003473 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003474 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003475 }
3476
3477 // Now the session's lifetime is bound by the auth timeout.
3478 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003479 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3480 new_session.get(),
3481 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003482
3483 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003484 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3485 new_session.get(),
3486 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003487 } else {
3488 // The new session is usable just before the old expiration.
3489 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003490 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3491 new_session.get(),
3492 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003493
3494 // Renewal does not extend the lifetime, so it is not usable beyond the
3495 // old expiration.
3496 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003497 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3498 new_session.get(),
3499 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003500 }
David Benjamin721e8b72016-08-03 13:13:17 -04003501 }
David Benjamin721e8b72016-08-03 13:13:17 -04003502}
3503
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003504TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003505 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3506 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003507 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003508 kTicketKeyLen));
3509 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3510}
3511
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003512TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003513 static const time_t kStartTime = 1001;
3514 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003515
David Benjaminc11ea9422017-08-29 16:33:21 -04003516 // We use session reuse as a proxy for ticket decryption success, hence
3517 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003518 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3519 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003520 std::numeric_limits<uint32_t>::max());
3521
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003522 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3523 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003525 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3526 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003527
David Benjamin1f0d54b2018-08-09 16:19:13 -05003528 // Initialize ticket_key with the current key and check that it was
3529 // initialized to something, not all zeros.
3530 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003531 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3532 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003533
David Benjaminc11ea9422017-08-29 16:33:21 -04003534 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003535 bssl::UniquePtr<SSL> client, server;
3536 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003537 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003538 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003539 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003540 session.get(), true /* reused */));
3541
David Benjaminc11ea9422017-08-29 16:33:21 -04003542 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003543 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003544 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003545 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003546 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003547 false /* NOT changed */));
3548
David Benjaminc11ea9422017-08-29 16:33:21 -04003549 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003550 g_current_time.tv_sec += 1;
3551 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003552 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3553 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3554 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003555
David Benjaminc11ea9422017-08-29 16:33:21 -04003556 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003557 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003558 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003559 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003560 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003561 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003562 false /* NOT changed */));
3563
David Benjaminc11ea9422017-08-29 16:33:21 -04003564 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003565 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003566 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003567 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003568 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3569 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003570
David Benjaminc11ea9422017-08-29 16:33:21 -04003571 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003572 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003573 new_session.get(), true /* reused */));
3574}
3575
David Benjamin0fc37ef2016-08-17 15:29:46 -04003576static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003577 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003578 SSL_set_SSL_CTX(ssl, ctx);
3579 return SSL_TLSEXT_ERR_OK;
3580}
3581
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003582TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003583 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003584 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003585 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003586 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003587
David Benjamin0fef3052016-11-18 15:11:10 +09003588 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3589 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003590
David Benjamin83a32122017-02-14 18:34:54 -05003591 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3592 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3593
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003594 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3595 ASSERT_TRUE(server_ctx2);
3596 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3597 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3598 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3599 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3600 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3601 sizeof(kOCSPResponse)));
3602 // Historically signing preferences would be lost in some cases with the
3603 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3604 // this doesn't happen when |version| is TLS 1.2, configure the private
3605 // key to only sign SHA-256.
3606 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3607 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003608
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003609 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3610 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003611
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003612 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3613 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003614
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003615 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003616
David Benjamin0fef3052016-11-18 15:11:10 +09003617 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003618 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3619 ASSERT_TRUE(peer);
3620 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003621
David Benjamin83a32122017-02-14 18:34:54 -05003622 // The client should have received |server_ctx2|'s SCT list.
3623 const uint8_t *data;
3624 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003625 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3626 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003627
3628 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003629 SSL_get0_ocsp_response(client_.get(), &data, &len);
3630 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003631}
3632
David Benjaminf0d8e222017-02-04 10:58:26 -05003633// Test that the early callback can swap the maximum version.
3634TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003635 bssl::UniquePtr<SSL_CTX> server_ctx =
3636 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003637 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003638 ASSERT_TRUE(server_ctx);
3639 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003640 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3641 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003642
David Benjaminf0d8e222017-02-04 10:58:26 -05003643 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003644 server_ctx.get(),
3645 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003646 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003647 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003648 }
3649
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003650 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003651 });
David Benjamin99620572016-08-30 00:35:36 -04003652
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003653 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003654 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003655 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003656 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003657}
3658
David Benjaminf0d8e222017-02-04 10:58:26 -05003659TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003660 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003661 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003662
David Benjaminf0d8e222017-02-04 10:58:26 -05003663 // Set valid TLS versions.
David Benjamin7a4df8e2021-10-14 13:56:03 -04003664 for (const auto &vers : kAllVersions) {
3665 SCOPED_TRACE(vers.name);
3666 if (vers.ssl_method == VersionParam::is_tls) {
3667 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3668 EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3669 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3670 EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3671 }
3672 }
David Benjamin2dc02042016-09-19 19:57:37 -04003673
David Benjaminf0d8e222017-02-04 10:58:26 -05003674 // Invalid TLS versions are rejected.
3675 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3676 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3677 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3678 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3679 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3680 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003681
David Benjaminf0d8e222017-02-04 10:58:26 -05003682 // Zero is the default version.
3683 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003684 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003685 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003686 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003687
David Benjamin9bb15f52018-06-26 00:07:40 -04003688 // SSL 3.0 is not available.
3689 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3690
David Benjamin2dc02042016-09-19 19:57:37 -04003691 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003692 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003693
David Benjamin7a4df8e2021-10-14 13:56:03 -04003694 // Set valid DTLS versions.
3695 for (const auto &vers : kAllVersions) {
3696 SCOPED_TRACE(vers.name);
3697 if (vers.ssl_method == VersionParam::is_dtls) {
3698 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3699 EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3700 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3701 EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3702 }
3703 }
David Benjamin2dc02042016-09-19 19:57:37 -04003704
David Benjamin7a4df8e2021-10-14 13:56:03 -04003705 // Invalid DTLS versions are rejected.
David Benjaminf0d8e222017-02-04 10:58:26 -05003706 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3707 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3708 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3709 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3710 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3711 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3712 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3713 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003714
David Benjamin7a4df8e2021-10-14 13:56:03 -04003715 // Zero is the default version.
David Benjaminf0d8e222017-02-04 10:58:26 -05003716 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003717 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003718 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003719 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003720}
3721
David Benjamin458334a2016-12-15 13:53:25 -05003722static const char *GetVersionName(uint16_t version) {
3723 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003724 case TLS1_VERSION:
3725 return "TLSv1";
3726 case TLS1_1_VERSION:
3727 return "TLSv1.1";
3728 case TLS1_2_VERSION:
3729 return "TLSv1.2";
3730 case TLS1_3_VERSION:
3731 return "TLSv1.3";
3732 case DTLS1_VERSION:
3733 return "DTLSv1";
3734 case DTLS1_2_VERSION:
3735 return "DTLSv1.2";
3736 default:
3737 return "???";
3738 }
3739}
3740
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003741TEST_P(SSLVersionTest, Version) {
3742 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003743
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003744 EXPECT_EQ(SSL_version(client_.get()), version());
3745 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003746
David Benjamin458334a2016-12-15 13:53:25 -05003747 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003748 const char *version_name = GetVersionName(version());
3749 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3750 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003751
3752 // Test SSL_SESSION reports the same name.
3753 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003754 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003755 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003756 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3757 EXPECT_EQ(strcmp(version_name, client_name), 0);
3758 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003759}
3760
David Benjamin9ef31f02016-10-31 18:01:13 -04003761// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3762// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003763TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003764 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3765
David Benjamin9ef31f02016-10-31 18:01:13 -04003766 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003767 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3768 sizeof(kALPNProtos)),
3769 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003770
3771 // The ALPN callback does not fail the handshake on error, so have the
3772 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003773 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003774 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003775 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003776 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3777 unsigned in_len, void *arg) -> int {
3778 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3779 if (SSL_get_pending_cipher(ssl) != nullptr &&
3780 SSL_version(ssl) == state->first) {
3781 state->second = true;
3782 }
3783 return SSL_TLSEXT_ERR_NOACK;
3784 },
3785 &callback_state);
3786
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003787 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003788
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003789 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003790}
3791
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003792TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003793 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3794 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003795 if (version() == TLS1_3_VERSION) {
3796 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003797 }
3798
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003799 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003800 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003801
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003802 EXPECT_FALSE(SSL_session_reused(client_.get()));
3803 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003804
3805 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003806 ASSERT_TRUE(SSL_clear(client_.get()));
3807 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003808
3809 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003810 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003811
3812 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003813 EXPECT_TRUE(SSL_session_reused(client_.get()));
3814 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003815}
3816
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003817TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3818 shed_handshake_config_ = false;
3819 ASSERT_TRUE(Connect());
3820 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3821
3822 // Reset everything.
3823 ASSERT_TRUE(SSL_clear(client_.get()));
3824 ASSERT_TRUE(SSL_clear(server_.get()));
3825
3826 // Now enable shedding, and connect a second time.
3827 shed_handshake_config_ = true;
3828 ASSERT_TRUE(Connect());
3829 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3830
3831 // |SSL_clear| should now fail.
3832 ASSERT_FALSE(SSL_clear(client_.get()));
3833 ASSERT_FALSE(SSL_clear(server_.get()));
3834}
3835
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003836static bool ChainsEqual(STACK_OF(X509) * chain,
3837 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003838 if (sk_X509_num(chain) != expected.size()) {
3839 return false;
3840 }
3841
3842 for (size_t i = 0; i < expected.size(); i++) {
3843 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3844 return false;
3845 }
3846 }
3847
3848 return true;
3849}
3850
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003851TEST_P(SSLVersionTest, AutoChain) {
3852 cert_ = GetChainTestCertificate();
3853 ASSERT_TRUE(cert_);
3854 key_ = GetChainTestKey();
3855 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003856 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003857 ASSERT_TRUE(intermediate);
3858
3859 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3860 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003861
3862 // Configure both client and server to accept any certificate. Add
3863 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003864 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3865 intermediate.get()));
3866 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3867 intermediate.get()));
3868 SSL_CTX_set_verify(client_ctx_.get(),
3869 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3870 nullptr);
3871 SSL_CTX_set_verify(server_ctx_.get(),
3872 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3873 nullptr);
3874 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3875 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003876
3877 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003878 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003879
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003880 EXPECT_TRUE(
3881 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3882 EXPECT_TRUE(
3883 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003884
3885 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003886 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3887 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3888 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003889
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003890 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3891 {cert_.get(), intermediate.get()}));
3892 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3893 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003894
3895 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003896 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3897 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3898 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003899
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003900 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3901 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003903 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3904 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003905}
3906
David Benjamin48063c22017-01-01 23:56:36 -05003907static bool ExpectBadWriteRetry() {
3908 int err = ERR_get_error();
3909 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3910 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3911 char buf[ERR_ERROR_STRING_BUF_LEN];
3912 ERR_error_string_n(err, buf, sizeof(buf));
3913 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3914 return false;
3915 }
3916
3917 if (ERR_peek_error() != 0) {
3918 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3919 return false;
3920 }
3921
3922 return true;
3923}
3924
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003925TEST_P(SSLVersionTest, SSLWriteRetry) {
3926 if (is_dtls()) {
3927 return;
David Benjamin48063c22017-01-01 23:56:36 -05003928 }
3929
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003930 for (bool enable_partial_write : {false, true}) {
3931 SCOPED_TRACE(enable_partial_write);
3932
David Benjamin48063c22017-01-01 23:56:36 -05003933 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003934 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3935
3936 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003937
3938 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003939 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003940 }
3941
3942 // Write without reading until the buffer is full and we have an unfinished
3943 // write. Keep a count so we may reread it again later. "hello!" will be
3944 // written in two chunks, "hello" and "!".
3945 char data[] = "hello!";
3946 static const int kChunkLen = 5; // The length of "hello".
3947 unsigned count = 0;
3948 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003949 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003950 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003951 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3952 break;
David Benjamin48063c22017-01-01 23:56:36 -05003953 }
3954
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003955 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003956
3957 count++;
3958 }
3959
3960 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003961 ASSERT_EQ(
3962 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3963 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003964
3965 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003966 ASSERT_EQ(SSL_get_error(client_.get(),
3967 SSL_write(client_.get(), data, kChunkLen - 1)),
3968 SSL_ERROR_SSL);
3969 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003970
3971 // Retrying with a different buffer pointer is not legal.
3972 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003973 ASSERT_EQ(SSL_get_error(client_.get(),
3974 SSL_write(client_.get(), data2, kChunkLen)),
3975 SSL_ERROR_SSL);
3976 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003977
3978 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003979 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3980 ASSERT_EQ(SSL_get_error(client_.get(),
3981 SSL_write(client_.get(), data2, kChunkLen)),
3982 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003983
3984 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003985 ASSERT_EQ(SSL_get_error(client_.get(),
3986 SSL_write(client_.get(), data2, kChunkLen - 1)),
3987 SSL_ERROR_SSL);
3988 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003989
3990 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003991 ASSERT_EQ(SSL_get_error(client_.get(),
3992 SSL_write(client_.get(), data, kChunkLen + 1)),
3993 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003994
3995 // Drain the buffer.
3996 char buf[20];
3997 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003998 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3999 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05004000 }
4001
4002 // Now that there is space, a retry with a larger buffer should flush the
4003 // pending record, skip over that many bytes of input (on assumption they
4004 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
4005 // is set, this will complete in two steps.
4006 char data3[] = "_____!";
4007 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004008 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
4009 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
4010 } else {
4011 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05004012 }
4013
4014 // Check the last write was correct. The data will be spread over two
4015 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004016 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4017 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4018 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
4019 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05004020 }
David Benjamin48063c22017-01-01 23:56:36 -05004021}
4022
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004023TEST_P(SSLVersionTest, RecordCallback) {
4024 for (bool test_server : {true, false}) {
4025 SCOPED_TRACE(test_server);
4026 ResetContexts();
David Benjamin5df5be1a2017-06-22 19:43:11 -04004027
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004028 bool read_seen = false;
4029 bool write_seen = false;
4030 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
4031 size_t len, SSL *ssl) {
4032 if (cb_type != SSL3_RT_HEADER) {
4033 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004034 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004035
4036 // The callback does not report a version for records.
4037 EXPECT_EQ(0, cb_version);
4038
4039 if (is_write) {
4040 write_seen = true;
4041 } else {
4042 read_seen = true;
4043 }
4044
4045 // Sanity-check that the record header is plausible.
4046 CBS cbs;
4047 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
4048 uint8_t type;
4049 uint16_t record_version, length;
4050 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
4051 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05004052 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004053 if (is_dtls()) {
4054 uint16_t epoch;
4055 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
4056 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
4057 ASSERT_TRUE(CBS_skip(&cbs, 6));
4058 }
4059 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
4060 EXPECT_EQ(0u, CBS_len(&cbs));
4061 };
4062 using CallbackType = decltype(cb);
4063 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
4064 SSL_CTX_set_msg_callback(
4065 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
4066 size_t len, SSL *ssl, void *arg) {
4067 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
4068 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
4069 });
4070 SSL_CTX_set_msg_callback_arg(ctx, &cb);
4071
4072 ASSERT_TRUE(Connect());
4073
4074 EXPECT_TRUE(read_seen);
4075 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09004076 }
David Benjamin9ef31f02016-10-31 18:01:13 -04004077}
4078
David Benjamina8614602017-09-06 15:40:19 -04004079TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04004080 ClientConfig config;
4081 config.servername = "host1";
4082
4083 SSL_CTX_set_tlsext_servername_callback(
4084 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
4085 // During the handshake, |SSL_get_servername| must match |config|.
4086 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
4087 EXPECT_STREQ(config_p->servername.c_str(),
4088 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
4089 return SSL_TLSEXT_ERR_OK;
4090 });
4091 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
4092
4093 ASSERT_TRUE(Connect(config));
4094 // After the handshake, it must also be available.
4095 EXPECT_STREQ(config.servername.c_str(),
4096 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4097
4098 // Establish a session under host1.
4099 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4100 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4101 bssl::UniquePtr<SSL_SESSION> session =
4102 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
4103
4104 // If the client resumes a session with a different name, |SSL_get_servername|
4105 // must return the new name.
4106 ASSERT_TRUE(session);
4107 config.session = session.get();
4108 config.servername = "host2";
4109 ASSERT_TRUE(Connect(config));
4110 EXPECT_STREQ(config.servername.c_str(),
4111 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4112}
4113
David Benjamin3d8f0802017-09-06 16:12:52 -04004114// Test that session cache mode bits are honored in the client session callback.
4115TEST_P(SSLVersionTest, ClientSessionCacheMode) {
4116 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
4117 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4118
4119 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
4120 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4121
4122 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
4123 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4124}
4125
Steven Valdez777a2392019-02-21 11:30:47 -05004126// Test that all versions survive tiny write buffers. In particular, TLS 1.3
4127// NewSessionTickets are written post-handshake. Servers that block
4128// |SSL_do_handshake| on writing them will deadlock if clients are not draining
4129// the buffer. Test that we do not do this.
4130TEST_P(SSLVersionTest, SmallBuffer) {
4131 // DTLS is a datagram protocol and requires packet-sized buffers.
4132 if (is_dtls()) {
4133 return;
4134 }
4135
4136 // Test both flushing NewSessionTickets with a zero-sized write and
4137 // non-zero-sized write.
4138 for (bool use_zero_write : {false, true}) {
4139 SCOPED_TRACE(use_zero_write);
4140
4141 g_last_session = nullptr;
4142 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4143 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
4144
4145 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
4146 server(SSL_new(server_ctx_.get()));
4147 ASSERT_TRUE(client);
4148 ASSERT_TRUE(server);
4149 SSL_set_connect_state(client.get());
4150 SSL_set_accept_state(server.get());
4151
4152 // Use a tiny buffer.
4153 BIO *bio1, *bio2;
4154 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
4155
4156 // SSL_set_bio takes ownership.
4157 SSL_set_bio(client.get(), bio1, bio1);
4158 SSL_set_bio(server.get(), bio2, bio2);
4159
4160 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4161 if (version() >= TLS1_3_VERSION) {
4162 // The post-handshake ticket should not have been processed yet.
4163 EXPECT_FALSE(g_last_session);
4164 }
4165
4166 if (use_zero_write) {
4167 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
4168 EXPECT_TRUE(g_last_session);
4169 }
4170
4171 // Send some data from server to client. If |use_zero_write| is false, this
4172 // will also flush the NewSessionTickets.
4173 static const char kMessage[] = "hello world";
4174 char buf[sizeof(kMessage)];
4175 for (;;) {
4176 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
4177 int server_err = SSL_get_error(server.get(), server_ret);
4178 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
4179 int client_err = SSL_get_error(client.get(), client_ret);
4180
4181 // The server will write a single record, so every iteration should see
4182 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
4183 // iteration, where both will complete.
4184 if (server_ret > 0) {
4185 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
4186 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
4187 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
4188 break;
4189 }
4190
4191 ASSERT_EQ(server_ret, -1);
4192 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
4193 ASSERT_EQ(client_ret, -1);
4194 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4195 }
4196
4197 // The NewSessionTickets should have been flushed and processed.
4198 EXPECT_TRUE(g_last_session);
4199 }
4200}
4201
Adam Langleye1e78132017-01-31 15:24:31 -08004202TEST(SSLTest, AddChainCertHack) {
4203 // Ensure that we don't accidently break the hack that we have in place to
4204 // keep curl and serf happy when they use an |X509| even after transfering
4205 // ownership.
4206
4207 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4208 ASSERT_TRUE(ctx);
4209 X509 *cert = GetTestCertificate().release();
4210 ASSERT_TRUE(cert);
4211 SSL_CTX_add0_chain_cert(ctx.get(), cert);
4212
4213 // This should not trigger a use-after-free.
4214 X509_cmp(cert, cert);
4215}
4216
David Benjaminb2ff2622017-02-03 17:06:18 -05004217TEST(SSLTest, GetCertificate) {
4218 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4219 ASSERT_TRUE(ctx);
4220 bssl::UniquePtr<X509> cert = GetTestCertificate();
4221 ASSERT_TRUE(cert);
4222 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4223 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4224 ASSERT_TRUE(ssl);
4225
4226 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4227 ASSERT_TRUE(cert2);
4228 X509 *cert3 = SSL_get_certificate(ssl.get());
4229 ASSERT_TRUE(cert3);
4230
4231 // The old and new certificates must be identical.
4232 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4233 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
4234
4235 uint8_t *der = nullptr;
4236 long der_len = i2d_X509(cert.get(), &der);
4237 ASSERT_LT(0, der_len);
4238 bssl::UniquePtr<uint8_t> free_der(der);
4239
4240 uint8_t *der2 = nullptr;
4241 long der2_len = i2d_X509(cert2, &der2);
4242 ASSERT_LT(0, der2_len);
4243 bssl::UniquePtr<uint8_t> free_der2(der2);
4244
4245 uint8_t *der3 = nullptr;
4246 long der3_len = i2d_X509(cert3, &der3);
4247 ASSERT_LT(0, der3_len);
4248 bssl::UniquePtr<uint8_t> free_der3(der3);
4249
4250 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05004251 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4252 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05004253}
4254
Adam Langleyd04ca952017-02-28 11:26:51 -08004255TEST(SSLTest, SetChainAndKeyMismatch) {
4256 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4257 ASSERT_TRUE(ctx);
4258
4259 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4260 ASSERT_TRUE(key);
4261 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4262 ASSERT_TRUE(leaf);
4263 std::vector<CRYPTO_BUFFER*> chain = {
4264 leaf.get(),
4265 };
4266
4267 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
4268 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
4269 key.get(), nullptr));
4270 ERR_clear_error();
4271}
4272
4273TEST(SSLTest, SetChainAndKey) {
4274 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4275 ASSERT_TRUE(client_ctx);
4276 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4277 ASSERT_TRUE(server_ctx);
4278
Adam Langley964256d2020-03-19 11:57:12 -07004279 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4280
Adam Langleyd04ca952017-02-28 11:26:51 -08004281 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4282 ASSERT_TRUE(key);
4283 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4284 ASSERT_TRUE(leaf);
4285 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4286 GetChainTestIntermediateBuffer();
4287 ASSERT_TRUE(intermediate);
4288 std::vector<CRYPTO_BUFFER*> chain = {
4289 leaf.get(), intermediate.get(),
4290 };
4291 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4292 chain.size(), key.get(), nullptr));
4293
Adam Langley964256d2020-03-19 11:57:12 -07004294 ASSERT_EQ(chain.size(),
4295 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4296
David Benjamin3a1dd462017-07-11 16:13:10 -04004297 SSL_CTX_set_custom_verify(
4298 client_ctx.get(), SSL_VERIFY_PEER,
4299 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4300 return ssl_verify_ok;
4301 });
Adam Langleyd04ca952017-02-28 11:26:51 -08004302
4303 bssl::UniquePtr<SSL> client, server;
4304 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004305 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08004306}
4307
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004308TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4309 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4310 ASSERT_TRUE(client_ctx);
4311 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4312 ASSERT_TRUE(server_ctx);
4313
4314 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4315 ASSERT_TRUE(key);
4316 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4317 ASSERT_TRUE(leaf);
4318 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4319 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4320 chain.size(), key.get(), nullptr));
4321
4322 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4323 // configuration, certificate verification should fail.
4324 bssl::UniquePtr<SSL> client, server;
4325 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4326 server_ctx.get()));
4327
4328 // Whereas with a verifier, the connection should succeed.
4329 SSL_CTX_set_custom_verify(
4330 client_ctx.get(), SSL_VERIFY_PEER,
4331 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4332 return ssl_verify_ok;
4333 });
4334 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4335 server_ctx.get()));
4336}
4337
4338TEST(SSLTest, CustomVerify) {
4339 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4340 ASSERT_TRUE(client_ctx);
4341 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4342 ASSERT_TRUE(server_ctx);
4343
4344 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4345 ASSERT_TRUE(key);
4346 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4347 ASSERT_TRUE(leaf);
4348 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4349 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4350 chain.size(), key.get(), nullptr));
4351
4352 SSL_CTX_set_custom_verify(
4353 client_ctx.get(), SSL_VERIFY_PEER,
4354 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4355 return ssl_verify_ok;
4356 });
4357
4358 bssl::UniquePtr<SSL> client, server;
4359 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4360 server_ctx.get()));
4361
4362 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4363 // connection.
4364 SSL_CTX_set_custom_verify(
4365 client_ctx.get(), SSL_VERIFY_PEER,
4366 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4367 return ssl_verify_invalid;
4368 });
4369
4370 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4371 server_ctx.get()));
4372
4373 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4374 // connection.
4375 SSL_CTX_set_custom_verify(
4376 client_ctx.get(), SSL_VERIFY_NONE,
4377 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4378 return ssl_verify_invalid;
4379 });
4380
4381 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4382 server_ctx.get()));
4383}
4384
David Benjamin71dfad42017-07-16 17:27:39 -04004385TEST(SSLTest, ClientCABuffers) {
4386 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4387 ASSERT_TRUE(client_ctx);
4388 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4389 ASSERT_TRUE(server_ctx);
4390
4391 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4392 ASSERT_TRUE(key);
4393 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4394 ASSERT_TRUE(leaf);
4395 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4396 GetChainTestIntermediateBuffer();
4397 ASSERT_TRUE(intermediate);
4398 std::vector<CRYPTO_BUFFER *> chain = {
4399 leaf.get(),
4400 intermediate.get(),
4401 };
4402 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4403 chain.size(), key.get(), nullptr));
4404
4405 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4406 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4407 ASSERT_TRUE(ca_name);
4408 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4409 sk_CRYPTO_BUFFER_new_null());
4410 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04004411 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04004412 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
4413
4414 // Configure client and server to accept all certificates.
4415 SSL_CTX_set_custom_verify(
4416 client_ctx.get(), SSL_VERIFY_PEER,
4417 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4418 return ssl_verify_ok;
4419 });
4420 SSL_CTX_set_custom_verify(
4421 server_ctx.get(), SSL_VERIFY_PEER,
4422 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4423 return ssl_verify_ok;
4424 });
4425
4426 bool cert_cb_called = false;
4427 SSL_CTX_set_cert_cb(
4428 client_ctx.get(),
4429 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04004430 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04004431 SSL_get0_server_requested_CAs(ssl);
4432 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
4433 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
4434 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
4435 CRYPTO_BUFFER_len(peer_name)));
4436 *reinterpret_cast<bool *>(arg) = true;
4437 return 1;
4438 },
4439 &cert_cb_called);
4440
4441 bssl::UniquePtr<SSL> client, server;
4442 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004443 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04004444 EXPECT_TRUE(cert_cb_called);
4445}
4446
David Benjamin91222b82017-03-09 20:10:56 -05004447// Configuring the empty cipher list, though an error, should still modify the
4448// configuration.
4449TEST(SSLTest, EmptyCipherList) {
4450 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4451 ASSERT_TRUE(ctx);
4452
4453 // Initially, the cipher list is not empty.
4454 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4455
4456 // Configuring the empty cipher list fails.
4457 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4458 ERR_clear_error();
4459
4460 // But the cipher list is still updated to empty.
4461 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4462}
4463
Adam Langley4c341d02017-03-08 19:33:21 -08004464// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4465// test |SSL_TICKET_AEAD_METHOD| can fail.
4466enum ssl_test_ticket_aead_failure_mode {
4467 ssl_test_ticket_aead_ok = 0,
4468 ssl_test_ticket_aead_seal_fail,
4469 ssl_test_ticket_aead_open_soft_fail,
4470 ssl_test_ticket_aead_open_hard_fail,
4471};
4472
4473struct ssl_test_ticket_aead_state {
4474 unsigned retry_count;
4475 ssl_test_ticket_aead_failure_mode failure_mode;
4476};
4477
4478static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4479 const CRYPTO_EX_DATA *from,
4480 void **from_d, int index,
4481 long argl, void *argp) {
4482 abort();
4483}
4484
4485static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4486 CRYPTO_EX_DATA *ad, int index,
4487 long argl, void *argp) {
4488 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4489 if (state == nullptr) {
4490 return;
4491 }
4492
4493 OPENSSL_free(state);
4494}
4495
4496static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4497static int g_ssl_test_ticket_aead_ex_index;
4498
4499static int ssl_test_ticket_aead_get_ex_index() {
4500 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4501 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4502 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4503 ssl_test_ticket_aead_ex_index_free);
4504 });
4505 return g_ssl_test_ticket_aead_ex_index;
4506}
4507
4508static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4509 return 1;
4510}
4511
4512static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4513 size_t max_out_len, const uint8_t *in,
4514 size_t in_len) {
4515 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4516 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4517
4518 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4519 max_out_len < in_len + 1) {
4520 return 0;
4521 }
4522
4523 OPENSSL_memmove(out, in, in_len);
4524 out[in_len] = 0xff;
4525 *out_len = in_len + 1;
4526
4527 return 1;
4528}
4529
4530static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4531 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4532 const uint8_t *in, size_t in_len) {
4533 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4534 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4535
4536 if (state->retry_count > 0) {
4537 state->retry_count--;
4538 return ssl_ticket_aead_retry;
4539 }
4540
4541 switch (state->failure_mode) {
4542 case ssl_test_ticket_aead_ok:
4543 break;
4544 case ssl_test_ticket_aead_seal_fail:
4545 // If |seal| failed then there shouldn't be any ticket to try and
4546 // decrypt.
4547 abort();
4548 break;
4549 case ssl_test_ticket_aead_open_soft_fail:
4550 return ssl_ticket_aead_ignore_ticket;
4551 case ssl_test_ticket_aead_open_hard_fail:
4552 return ssl_ticket_aead_error;
4553 }
4554
4555 if (in_len == 0 || in[in_len - 1] != 0xff) {
4556 return ssl_ticket_aead_ignore_ticket;
4557 }
4558
4559 if (max_out_len < in_len - 1) {
4560 return ssl_ticket_aead_error;
4561 }
4562
4563 OPENSSL_memmove(out, in, in_len - 1);
4564 *out_len = in_len - 1;
4565 return ssl_ticket_aead_success;
4566}
4567
4568static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4569 ssl_test_ticket_aead_max_overhead,
4570 ssl_test_ticket_aead_seal,
4571 ssl_test_ticket_aead_open,
4572};
4573
4574static void ConnectClientAndServerWithTicketMethod(
4575 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4576 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4577 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4578 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4579 ASSERT_TRUE(client);
4580 ASSERT_TRUE(server);
4581 SSL_set_connect_state(client.get());
4582 SSL_set_accept_state(server.get());
4583
4584 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4585 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4586 ASSERT_TRUE(state);
4587 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4588 state->retry_count = retry_count;
4589 state->failure_mode = failure_mode;
4590
4591 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4592 state));
4593
4594 SSL_set_session(client.get(), session);
4595
4596 BIO *bio1, *bio2;
4597 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4598
4599 // SSL_set_bio takes ownership.
4600 SSL_set_bio(client.get(), bio1, bio1);
4601 SSL_set_bio(server.get(), bio2, bio2);
4602
4603 if (CompleteHandshakes(client.get(), server.get())) {
4604 *out_client = std::move(client);
4605 *out_server = std::move(server);
4606 } else {
4607 out_client->reset();
4608 out_server->reset();
4609 }
4610}
4611
David Benjaminc9775322018-04-13 16:39:12 -04004612using TicketAEADMethodParam =
4613 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4614
Adam Langley4c341d02017-03-08 19:33:21 -08004615class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004616 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004617
4618TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004619 bssl::UniquePtr<SSL_CTX> server_ctx =
4620 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004621 ASSERT_TRUE(server_ctx);
4622 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4623 ASSERT_TRUE(client_ctx);
4624
4625 const uint16_t version = testing::get<0>(GetParam());
4626 const unsigned retry_count = testing::get<1>(GetParam());
4627 const ssl_test_ticket_aead_failure_mode failure_mode =
4628 testing::get<2>(GetParam());
4629
Adam Langley4c341d02017-03-08 19:33:21 -08004630 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4631 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4632 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4633 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4634
4635 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4636 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4637 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4638 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004639 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004640
4641 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4642
4643 bssl::UniquePtr<SSL> client, server;
4644 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4645 server_ctx.get(), retry_count,
4646 failure_mode, nullptr);
4647 switch (failure_mode) {
4648 case ssl_test_ticket_aead_ok:
4649 case ssl_test_ticket_aead_open_hard_fail:
4650 case ssl_test_ticket_aead_open_soft_fail:
4651 ASSERT_TRUE(client);
4652 break;
4653 case ssl_test_ticket_aead_seal_fail:
4654 EXPECT_FALSE(client);
4655 return;
4656 }
4657 EXPECT_FALSE(SSL_session_reused(client.get()));
4658 EXPECT_FALSE(SSL_session_reused(server.get()));
4659
Steven Valdez777a2392019-02-21 11:30:47 -05004660 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004661 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004662 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4663 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004664 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004665 switch (failure_mode) {
4666 case ssl_test_ticket_aead_ok:
4667 ASSERT_TRUE(client);
4668 EXPECT_TRUE(SSL_session_reused(client.get()));
4669 EXPECT_TRUE(SSL_session_reused(server.get()));
4670 break;
4671 case ssl_test_ticket_aead_seal_fail:
4672 abort();
4673 break;
4674 case ssl_test_ticket_aead_open_hard_fail:
4675 EXPECT_FALSE(client);
4676 break;
4677 case ssl_test_ticket_aead_open_soft_fail:
4678 ASSERT_TRUE(client);
4679 EXPECT_FALSE(SSL_session_reused(client.get()));
4680 EXPECT_FALSE(SSL_session_reused(server.get()));
4681 }
4682}
4683
David Benjaminc9775322018-04-13 16:39:12 -04004684std::string TicketAEADMethodParamToString(
4685 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4686 std::string ret = GetVersionName(std::get<0>(params.param));
4687 // GTest only allows alphanumeric characters and '_' in the parameter
4688 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4689 for (auto it = ret.begin(); it != ret.end();) {
4690 if (*it == '.' || *it == 'v') {
4691 it = ret.erase(it);
4692 } else {
4693 ++it;
4694 }
4695 }
4696 char retry_count[256];
David Benjamin4f1fae32021-12-15 11:41:10 -05004697 snprintf(retry_count, sizeof(retry_count), "%u", std::get<1>(params.param));
David Benjaminc9775322018-04-13 16:39:12 -04004698 ret += "_";
4699 ret += retry_count;
4700 ret += "Retries_";
4701 switch (std::get<2>(params.param)) {
4702 case ssl_test_ticket_aead_ok:
4703 ret += "OK";
4704 break;
4705 case ssl_test_ticket_aead_seal_fail:
4706 ret += "SealFail";
4707 break;
4708 case ssl_test_ticket_aead_open_soft_fail:
4709 ret += "OpenSoftFail";
4710 break;
4711 case ssl_test_ticket_aead_open_hard_fail:
4712 ret += "OpenHardFail";
4713 break;
4714 }
4715 return ret;
4716}
4717
David Benjaminbe7006a2019-04-09 18:05:02 -05004718INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004719 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004720 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4721 testing::Values(0, 1, 2),
4722 testing::Values(ssl_test_ticket_aead_ok,
4723 ssl_test_ticket_aead_seal_fail,
4724 ssl_test_ticket_aead_open_soft_fail,
4725 ssl_test_ticket_aead_open_hard_fail)),
4726 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004727
David Benjaminca743582017-06-15 17:51:35 -04004728TEST(SSLTest, SelectNextProto) {
4729 uint8_t *result;
4730 uint8_t result_len;
4731
4732 // If there is an overlap, it should be returned.
4733 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4734 SSL_select_next_proto(&result, &result_len,
4735 (const uint8_t *)"\1a\2bb\3ccc", 9,
4736 (const uint8_t *)"\1x\1y\1a\1z", 8));
4737 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4738
4739 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4740 SSL_select_next_proto(&result, &result_len,
4741 (const uint8_t *)"\1a\2bb\3ccc", 9,
4742 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4743 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4744
4745 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4746 SSL_select_next_proto(&result, &result_len,
4747 (const uint8_t *)"\1a\2bb\3ccc", 9,
4748 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4749 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4750
4751 // Peer preference order takes precedence over local.
4752 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4753 SSL_select_next_proto(&result, &result_len,
4754 (const uint8_t *)"\1a\2bb\3ccc", 9,
4755 (const uint8_t *)"\3ccc\2bb\1a", 9));
4756 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4757
4758 // If there is no overlap, return the first local protocol.
4759 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4760 SSL_select_next_proto(&result, &result_len,
4761 (const uint8_t *)"\1a\2bb\3ccc", 9,
4762 (const uint8_t *)"\1x\2yy\3zzz", 9));
4763 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4764
4765 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4766 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4767 (const uint8_t *)"\1x\2yy\3zzz", 9));
4768 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4769}
4770
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004771TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004772 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004773 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004774 ASSERT_TRUE(client_ctx);
4775 ASSERT_TRUE(server_ctx);
4776
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004777 bssl::UniquePtr<SSL> client, server;
4778 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004779 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004780
4781 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4782 std::vector<uint8_t> prefix(
4783 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004784 body(record.size()),
4785 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004786 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4787 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004788 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004789
4790 std::vector<uint8_t> sealed;
4791 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4792 sealed.insert(sealed.end(), body.begin(), body.end());
4793 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4794 std::vector<uint8_t> sealed_copy = sealed;
4795
4796 bssl::Span<uint8_t> plaintext;
4797 size_t record_len;
4798 uint8_t alert = 255;
4799 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4800 bssl::MakeSpan(sealed)),
4801 bssl::OpenRecordResult::kOK);
4802 EXPECT_EQ(record_len, sealed.size());
4803 EXPECT_EQ(plaintext, record);
4804 EXPECT_EQ(255, alert);
4805}
4806
4807TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004808 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004809 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004810 ASSERT_TRUE(client_ctx);
4811 ASSERT_TRUE(server_ctx);
4812
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004813 bssl::UniquePtr<SSL> client, server;
4814 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004815 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004816
4817 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4818 std::vector<uint8_t> record = plaintext;
4819 std::vector<uint8_t> prefix(
4820 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004821 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004822 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4823 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004824 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004825 record.insert(record.begin(), prefix.begin(), prefix.end());
4826 record.insert(record.end(), suffix.begin(), suffix.end());
4827
4828 bssl::Span<uint8_t> result;
4829 size_t record_len;
4830 uint8_t alert;
4831 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4832 bssl::MakeSpan(record)),
4833 bssl::OpenRecordResult::kOK);
4834 EXPECT_EQ(record_len, record.size());
4835 EXPECT_EQ(plaintext, result);
4836}
4837
4838TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004839 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004840 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004841 ASSERT_TRUE(client_ctx);
4842 ASSERT_TRUE(server_ctx);
4843
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004844 bssl::UniquePtr<SSL> client, server;
4845 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004846 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004847
4848 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4849 std::vector<uint8_t> record = plaintext;
4850 std::vector<uint8_t> prefix(
4851 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004852 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004853 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4854 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004855 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004856 record.insert(record.begin(), prefix.begin(), prefix.end());
4857 record.insert(record.end(), suffix.begin(), suffix.end());
4858 record.insert(record.end(), {5, 4, 3, 2, 1});
4859
4860 bssl::Span<uint8_t> result;
4861 size_t record_len;
4862 uint8_t alert;
4863 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4864 bssl::MakeSpan(record)),
4865 bssl::OpenRecordResult::kOK);
4866 EXPECT_EQ(record_len, record.size() - 5);
4867 EXPECT_EQ(plaintext, result);
4868}
4869
4870TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004871 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004872 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004873 ASSERT_TRUE(client_ctx);
4874 ASSERT_TRUE(server_ctx);
4875
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004876 bssl::UniquePtr<SSL> client, server;
4877 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004878 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004879
4880 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4881 std::vector<uint8_t> prefix(
4882 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004883 body(record.size()),
4884 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004885
4886 auto expect_err = []() {
4887 int err = ERR_get_error();
4888 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4889 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4890 ERR_clear_error();
4891 };
4892 EXPECT_FALSE(bssl::SealRecord(
4893 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004894 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004895 expect_err();
4896 EXPECT_FALSE(bssl::SealRecord(
4897 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004898 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004899 expect_err();
4900
4901 EXPECT_FALSE(
4902 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4903 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004904 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004905 expect_err();
4906 EXPECT_FALSE(
4907 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4908 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004909 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004910 expect_err();
4911
4912 EXPECT_FALSE(bssl::SealRecord(
4913 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004914 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004915 expect_err();
4916 EXPECT_FALSE(bssl::SealRecord(
4917 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004918 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004919 expect_err();
4920}
4921
David Benjamin617b8182017-08-29 15:33:10 -04004922// The client should gracefully handle no suitable ciphers being enabled.
4923TEST(SSLTest, NoCiphersAvailable) {
4924 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4925 ASSERT_TRUE(ctx);
4926
4927 // Configure |client_ctx| with a cipher list that does not intersect with its
4928 // version configuration.
4929 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4930 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4931 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4932
4933 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4934 ASSERT_TRUE(ssl);
4935 SSL_set_connect_state(ssl.get());
4936
4937 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4938 ASSERT_TRUE(rbio);
4939 ASSERT_TRUE(wbio);
4940 SSL_set0_rbio(ssl.get(), rbio.release());
4941 SSL_set0_wbio(ssl.get(), wbio.release());
4942
4943 int ret = SSL_do_handshake(ssl.get());
4944 EXPECT_EQ(-1, ret);
4945 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4946 uint32_t err = ERR_get_error();
4947 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4948 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4949}
4950
David Benjamina4bafd32017-10-03 15:06:29 -04004951TEST_P(SSLVersionTest, SessionVersion) {
4952 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4953 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4954
4955 bssl::UniquePtr<SSL_SESSION> session =
4956 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4957 ASSERT_TRUE(session);
4958 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4959
4960 // Sessions in TLS 1.3 and later should be single-use.
4961 EXPECT_EQ(version() == TLS1_3_VERSION,
4962 !!SSL_SESSION_should_be_single_use(session.get()));
4963
4964 // Making fake sessions for testing works.
4965 session.reset(SSL_SESSION_new(client_ctx_.get()));
4966 ASSERT_TRUE(session);
4967 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4968 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4969}
4970
David Benjaminfdb7a352017-10-12 17:34:18 -04004971TEST_P(SSLVersionTest, SSLPending) {
4972 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4973 ASSERT_TRUE(ssl);
4974 EXPECT_EQ(0, SSL_pending(ssl.get()));
4975
4976 ASSERT_TRUE(Connect());
4977 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004978 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004979
4980 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4981 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4982 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004983 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004984
4985 char buf[10];
4986 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4987 EXPECT_EQ(5, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004988 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004989
4990 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4991 EXPECT_EQ(4, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004992 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004993
4994 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4995 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004996 if (is_dtls()) {
4997 // In DTLS, the two records would have been read as a single datagram and
4998 // buffered inside |client_|. Thus, |SSL_has_pending| should return true.
4999 //
5000 // This test is slightly unrealistic. It relies on |ConnectClientAndServer|
5001 // using a |BIO| pair, which does not preserve datagram boundaries. Reading
5002 // 1 byte, then 4 bytes, from the first record also relies on
5003 // https://crbug.com/boringssl/65. But it does test the codepaths. When
5004 // fixing either of these bugs, this test may need to be redone.
5005 EXPECT_EQ(1, SSL_has_pending(client_.get()));
5006 } else {
5007 // In TLS, we do not overread, so |SSL_has_pending| should report no data is
5008 // buffered.
5009 EXPECT_EQ(0, SSL_has_pending(client_.get()));
5010 }
David Benjaminfdb7a352017-10-12 17:34:18 -04005011
5012 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
5013 EXPECT_EQ(3, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005014 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005015}
5016
David Benjamina031b612017-10-11 20:48:25 -04005017// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
5018TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04005019 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04005020 ASSERT_TRUE(ctx);
5021 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
5022 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
5023
David Benjamina031b612017-10-11 20:48:25 -04005024 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
5025
5026 bssl::UniquePtr<SSL> client, server;
5027 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
5028
5029 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
5030 ADD_FAILURE() << "New session callback called during SSL_shutdown";
5031 return 0;
5032 });
5033
5034 // Send close_notify.
5035 EXPECT_EQ(0, SSL_shutdown(server.get()));
5036 EXPECT_EQ(0, SSL_shutdown(client.get()));
5037
5038 // Receive close_notify.
5039 EXPECT_EQ(1, SSL_shutdown(server.get()));
5040 EXPECT_EQ(1, SSL_shutdown(client.get()));
5041}
5042
David Benjamin6cc352e2017-11-02 17:21:39 -04005043TEST(SSLTest, SignatureAlgorithmProperties) {
5044 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
5045 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
5046 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
5047
5048 EXPECT_EQ(EVP_PKEY_RSA,
5049 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5050 EXPECT_EQ(EVP_md5_sha1(),
5051 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5052 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5053
5054 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
5055 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5056 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
5057 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5058 EXPECT_FALSE(
5059 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
5060
5061 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04005062 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005063 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04005064 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5065 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005066}
5067
Adam Langley85967952018-07-03 08:04:58 -07005068static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
5069 size_t in_len) {
5070 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005071 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07005072 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005073 }
5074 }
5075
5076 SSL_set_app_data(ssl, XORCompressFunc);
5077
Adam Langley85967952018-07-03 08:04:58 -07005078 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005079}
5080
Adam Langley85967952018-07-03 08:04:58 -07005081static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
5082 size_t uncompressed_len, const uint8_t *in,
5083 size_t in_len) {
5084 if (in_len != uncompressed_len) {
5085 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005086 }
5087
5088 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07005089 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
5090 if (*out == nullptr) {
5091 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005092 }
5093
Adam Langley85967952018-07-03 08:04:58 -07005094 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005095 data[i] = in[i] ^ 0x55;
5096 }
5097
5098 SSL_set_app_data(ssl, XORDecompressFunc);
5099
Adam Langley85967952018-07-03 08:04:58 -07005100 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005101}
5102
5103TEST(SSLTest, CertCompression) {
5104 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005105 bssl::UniquePtr<SSL_CTX> server_ctx(
5106 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07005107 ASSERT_TRUE(client_ctx);
5108 ASSERT_TRUE(server_ctx);
5109
Adam Langley0080d832018-06-07 16:39:49 -07005110 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5111 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5112 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5113 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5114 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5115 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5116
5117 bssl::UniquePtr<SSL> client, server;
5118 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5119 server_ctx.get()));
5120
5121 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
5122 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
5123}
5124
Adam Langleyddb57cf2018-01-26 09:17:53 -08005125void MoveBIOs(SSL *dest, SSL *src) {
5126 BIO *rbio = SSL_get_rbio(src);
5127 BIO_up_ref(rbio);
5128 SSL_set0_rbio(dest, rbio);
5129
5130 BIO *wbio = SSL_get_wbio(src);
5131 BIO_up_ref(wbio);
5132 SSL_set0_wbio(dest, wbio);
5133
5134 SSL_set0_rbio(src, nullptr);
5135 SSL_set0_wbio(src, nullptr);
5136}
5137
5138TEST(SSLTest, Handoff) {
5139 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5140 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005141 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
5142 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005143 ASSERT_TRUE(client_ctx);
5144 ASSERT_TRUE(server_ctx);
5145 ASSERT_TRUE(handshaker_ctx);
5146
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005147 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
5148 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005149 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005150 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05005151 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005152 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005153
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005154 for (bool early_data : {false, true}) {
5155 SCOPED_TRACE(early_data);
5156 for (bool is_resume : {false, true}) {
5157 SCOPED_TRACE(is_resume);
5158 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005159 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5160 server_ctx.get()));
5161 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005162 if (is_resume) {
5163 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04005164 SSL_set_session(client.get(), g_last_session.get());
5165 if (early_data) {
5166 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
5167 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005168 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04005169
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005170
5171 int client_ret = SSL_do_handshake(client.get());
5172 int client_err = SSL_get_error(client.get(), client_ret);
5173
5174 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005175 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005176 ASSERT_EQ(client_err, 0);
5177 EXPECT_TRUE(SSL_in_early_data(client.get()));
5178 // Attempt to write early data.
5179 byte_written = 43;
5180 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5181 } else {
5182 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5183 }
5184
5185 int server_ret = SSL_do_handshake(server.get());
5186 int server_err = SSL_get_error(server.get(), server_ret);
5187 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5188
5189 ScopedCBB cbb;
5190 Array<uint8_t> handoff;
5191 SSL_CLIENT_HELLO hello;
5192 ASSERT_TRUE(CBB_init(cbb.get(), 256));
5193 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5194 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5195
5196 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
5197 // Note split handshakes determines 0-RTT support, for both the current
5198 // handshake and newly-issued tickets, entirely by |handshaker|. There is
5199 // no need to call |SSL_set_early_data_enabled| on |server|.
5200 SSL_set_early_data_enabled(handshaker.get(), 1);
5201 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5202
5203 MoveBIOs(handshaker.get(), server.get());
5204
5205 int handshake_ret = SSL_do_handshake(handshaker.get());
5206 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5207 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5208
5209 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08005210 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005211 handshake_ret = SSL_do_handshake(handshaker.get());
5212 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5213 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5214
5215 ScopedCBB cbb_handback;
5216 Array<uint8_t> handback;
5217 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5218 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5219 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5220
5221 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
5222 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5223
5224 MoveBIOs(server2.get(), handshaker.get());
5225 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5226 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
5227
David Benjamin9b2cdb72021-04-01 23:21:53 -04005228 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005229 // In this case, one byte of early data has already been written above.
5230 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5231 } else {
5232 byte_written = 42;
5233 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5234 }
5235 uint8_t byte;
5236 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5237 EXPECT_EQ(byte_written, byte);
5238
5239 byte = 44;
5240 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5241 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5242 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005243 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005244 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08005245}
5246
5247TEST(SSLTest, HandoffDeclined) {
5248 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005249 bssl::UniquePtr<SSL_CTX> server_ctx(
5250 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005251 ASSERT_TRUE(client_ctx);
5252 ASSERT_TRUE(server_ctx);
5253
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005254 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Adam Langleyddb57cf2018-01-26 09:17:53 -08005255 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5256
Adam Langleyddb57cf2018-01-26 09:17:53 -08005257 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005258 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5259 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005260
5261 int client_ret = SSL_do_handshake(client.get());
5262 int client_err = SSL_get_error(client.get(), client_ret);
5263 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5264
5265 int server_ret = SSL_do_handshake(server.get());
5266 int server_err = SSL_get_error(server.get(), server_ret);
5267 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5268
5269 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005270 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005271 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005272 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005273
5274 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5275
5276 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5277
5278 uint8_t byte = 42;
5279 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5280 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5281 EXPECT_EQ(42, byte);
5282
5283 byte = 43;
5284 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5285 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5286 EXPECT_EQ(43, byte);
5287}
5288
Adam Langley826ce152018-08-03 10:31:21 -07005289static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5290 std::string ret = "{";
5291
5292 for (uint16_t v : sigalgs) {
5293 if (ret.size() > 1) {
5294 ret += ", ";
5295 }
5296
5297 char buf[8];
5298 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5299 buf[sizeof(buf)-1] = 0;
5300 ret += std::string(buf);
5301 }
5302
5303 ret += "}";
5304 return ret;
5305}
5306
5307void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5308 Span<const uint16_t> actual) {
5309 bool matches = false;
5310 if (expected.size() == actual.size()) {
5311 matches = true;
5312
5313 for (size_t i = 0; i < expected.size(); i++) {
5314 if (expected[i] != actual[i]) {
5315 matches = false;
5316 break;
5317 }
5318 }
5319 }
5320
5321 if (!matches) {
5322 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5323 << " got: " << SigAlgsToString(actual);
5324 }
5325}
5326
5327TEST(SSLTest, SigAlgs) {
5328 static const struct {
5329 std::vector<int> input;
5330 bool ok;
5331 std::vector<uint16_t> expected;
5332 } kTests[] = {
5333 {{}, true, {}},
5334 {{1}, false, {}},
5335 {{1, 2, 3}, false, {}},
5336 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5337 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5338
5339 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5340 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5341 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5342 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5343 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5344 true,
5345 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5346 };
5347
5348 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5349
5350 unsigned n = 1;
5351 for (const auto &test : kTests) {
5352 SCOPED_TRACE(n++);
5353
5354 const bool ok =
5355 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5356 EXPECT_EQ(ok, test.ok);
5357
5358 if (!ok) {
5359 ERR_clear_error();
5360 }
5361
5362 if (!test.ok) {
5363 continue;
5364 }
5365
5366 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5367 }
5368}
5369
5370TEST(SSLTest, SigAlgsList) {
5371 static const struct {
5372 const char *input;
5373 bool ok;
5374 std::vector<uint16_t> expected;
5375 } kTests[] = {
5376 {"", false, {}},
5377 {":", false, {}},
5378 {"+", false, {}},
5379 {"RSA", false, {}},
5380 {"RSA+", false, {}},
5381 {"RSA+SHA256:", false, {}},
5382 {":RSA+SHA256:", false, {}},
5383 {":RSA+SHA256+:", false, {}},
5384 {"!", false, {}},
5385 {"\x01", false, {}},
5386 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5387 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5388
5389 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5390 {"RSA+SHA256:ed25519",
5391 true,
5392 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5393 {"ECDSA+SHA256:RSA+SHA512",
5394 true,
5395 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5396 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5397 true,
5398 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5399 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5400 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5401 };
5402
5403 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5404
5405 unsigned n = 1;
5406 for (const auto &test : kTests) {
5407 SCOPED_TRACE(n++);
5408
5409 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5410 EXPECT_EQ(ok, test.ok);
5411
5412 if (!ok) {
5413 if (test.ok) {
5414 ERR_print_errors_fp(stderr);
5415 }
5416 ERR_clear_error();
5417 }
5418
5419 if (!test.ok) {
5420 continue;
5421 }
5422
5423 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5424 }
5425}
5426
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005427TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5428 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5429 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5430
5431 // handoff is a handoff message that has been artificially modified to pretend
5432 // that only cipher 0x0A is supported. When it is applied to |server|, all
5433 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005434 //
5435 // To make a new one of these, try sticking this in the |Handoff| test above:
5436 //
5437 // hexdump(stderr, "", handoff.data(), handoff.size());
5438 // sed -e 's/\(..\)/0x\1, /g'
5439 //
5440 // and modify serialize_features() to emit only cipher 0x0A.
5441
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005442 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005443 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5444 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5445 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5446 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5447 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005448 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5449 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005450 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5451 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5452 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5453 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5454 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
5455 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5456 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005457 };
5458
5459 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5460 ASSERT_TRUE(
5461 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5462 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5463}
5464
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005465TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5466 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5467 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5468
5469 // handoff is a handoff message that has been artificially modified to pretend
5470 // that only one curve is supported. When it is applied to |server|, all
5471 // curves but that one should be removed.
5472 //
5473 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5474 // these.
5475 uint8_t handoff[] = {
5476 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5477 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5478 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5479 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5480 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5481 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5482 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5483 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5484 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5485 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5486 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5487 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5488 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5489 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5490 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5491 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5492 0x02, 0x00, 0x17,
5493 };
5494
5495 // The zero length means that the default list of groups is used.
5496 EXPECT_EQ(0u, server->config->supported_group_list.size());
5497 ASSERT_TRUE(
5498 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5499 EXPECT_EQ(1u, server->config->supported_group_list.size());
5500}
5501
Adam Langleyba9ad662018-12-17 13:59:38 -08005502TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5503 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5504 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005505 bssl::UniquePtr<SSL_CTX> server_ctx(
5506 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005507 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5508 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005509
5510 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5511 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5512 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5513
5514 bssl::UniquePtr<SSL> client, server;
5515 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5516 server_ctx.get()));
5517
5518 BIO *client_wbio = SSL_get_wbio(client.get());
5519 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5520 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5521 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5522 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5523 EXPECT_NE(0u, BIO_wpending(client_wbio));
5524}
5525
David Benjamin5869eb32018-07-17 00:59:45 -04005526TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5527 // Configure the server to request client certificates.
5528 SSL_CTX_set_custom_verify(
5529 server_ctx_.get(), SSL_VERIFY_PEER,
5530 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5531
5532 // Configure the client to reject the server certificate.
5533 SSL_CTX_set_custom_verify(
5534 client_ctx_.get(), SSL_VERIFY_PEER,
5535 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5536
5537 // cert_cb should not be called. Verification should fail first.
5538 SSL_CTX_set_cert_cb(client_ctx_.get(),
5539 [](SSL *ssl, void *arg) {
5540 ADD_FAILURE() << "cert_cb unexpectedly called";
5541 return 0;
5542 },
5543 nullptr);
5544
5545 bssl::UniquePtr<SSL> client, server;
5546 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5547 server_ctx_.get()));
5548}
5549
David Benjamin492c9aa2018-08-31 16:35:22 -05005550// Test that ticket-based sessions on the client get fake session IDs.
5551TEST_P(SSLVersionTest, FakeIDsForTickets) {
5552 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5553 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5554
5555 bssl::UniquePtr<SSL_SESSION> session =
5556 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5557 ASSERT_TRUE(session);
5558
5559 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5560 unsigned session_id_length;
5561 SSL_SESSION_get_id(session.get(), &session_id_length);
5562 EXPECT_NE(session_id_length, 0u);
5563}
5564
David Benjamin6c04bd12018-07-19 18:13:09 -04005565// These tests test multi-threaded behavior. They are intended to run with
5566// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005567#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005568TEST_P(SSLVersionTest, SessionCacheThreads) {
5569 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5570 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5571 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5572
5573 if (version() == TLS1_3_VERSION) {
5574 // Our TLS 1.3 implementation does not support stateful resumption.
5575 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5576 return;
5577 }
5578
5579 // Establish two client sessions to test with.
5580 bssl::UniquePtr<SSL_SESSION> session1 =
5581 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5582 ASSERT_TRUE(session1);
5583 bssl::UniquePtr<SSL_SESSION> session2 =
5584 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5585 ASSERT_TRUE(session2);
5586
5587 auto connect_with_session = [&](SSL_SESSION *session) {
5588 ClientConfig config;
5589 config.session = session;
5590 UniquePtr<SSL> client, server;
5591 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5592 server_ctx_.get(), config));
5593 };
5594
5595 // Resume sessions in parallel with establishing new ones.
5596 {
5597 std::vector<std::thread> threads;
5598 threads.emplace_back([&] { connect_with_session(nullptr); });
5599 threads.emplace_back([&] { connect_with_session(nullptr); });
5600 threads.emplace_back([&] { connect_with_session(session1.get()); });
5601 threads.emplace_back([&] { connect_with_session(session1.get()); });
5602 threads.emplace_back([&] { connect_with_session(session2.get()); });
5603 threads.emplace_back([&] { connect_with_session(session2.get()); });
5604 for (auto &thread : threads) {
5605 thread.join();
5606 }
5607 }
5608
David Benjamina10017c2021-06-16 16:00:13 -04005609 // Hit the maximum session cache size across multiple threads, to test the
5610 // size enforcement logic.
David Benjamin6c04bd12018-07-19 18:13:09 -04005611 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5612 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5613 {
5614 std::vector<std::thread> threads;
5615 for (int i = 0; i < 4; i++) {
5616 threads.emplace_back([&]() {
5617 connect_with_session(nullptr);
5618 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5619 });
5620 }
5621 for (auto &thread : threads) {
5622 thread.join();
5623 }
5624 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5625 }
David Benjamina10017c2021-06-16 16:00:13 -04005626
5627 // Reset the session cache, this time with a mock clock.
5628 ASSERT_NO_FATAL_FAILURE(ResetContexts());
5629 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5630 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5631 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5632 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
5633
5634 // Make some sessions at an arbitrary start time. Then expire them.
5635 g_current_time.tv_sec = 1000;
5636 bssl::UniquePtr<SSL_SESSION> expired_session1 =
5637 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5638 ASSERT_TRUE(expired_session1);
5639 bssl::UniquePtr<SSL_SESSION> expired_session2 =
5640 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5641 ASSERT_TRUE(expired_session2);
5642 g_current_time.tv_sec += 100 * SSL_DEFAULT_SESSION_TIMEOUT;
5643
5644 session1 = CreateClientSession(client_ctx_.get(), server_ctx_.get());
5645 ASSERT_TRUE(session1);
5646
5647 // Every 256 connections, we flush stale sessions from the session cache. Test
5648 // this logic is correctly synchronized with other connection attempts.
5649 static const int kNumConnections = 256;
5650 {
5651 std::vector<std::thread> threads;
5652 threads.emplace_back([&] {
5653 for (int i = 0; i < kNumConnections; i++) {
5654 connect_with_session(nullptr);
5655 }
5656 });
5657 threads.emplace_back([&] {
5658 for (int i = 0; i < kNumConnections; i++) {
5659 connect_with_session(nullptr);
5660 }
5661 });
5662 threads.emplace_back([&] {
5663 // Never connect with |expired_session2|. The session cache eagerly
5664 // removes expired sessions when it sees them. Leaving |expired_session2|
5665 // untouched ensures it is instead cleared by periodic flushing.
5666 for (int i = 0; i < kNumConnections; i++) {
5667 connect_with_session(expired_session1.get());
5668 }
5669 });
5670 threads.emplace_back([&] {
5671 for (int i = 0; i < kNumConnections; i++) {
5672 connect_with_session(session1.get());
5673 }
5674 });
5675 for (auto &thread : threads) {
5676 thread.join();
5677 }
5678 }
David Benjamin6c04bd12018-07-19 18:13:09 -04005679}
5680
5681TEST_P(SSLVersionTest, SessionTicketThreads) {
5682 for (bool renew_ticket : {false, true}) {
5683 SCOPED_TRACE(renew_ticket);
5684 ResetContexts();
5685 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5686 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5687 if (renew_ticket) {
5688 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5689 }
5690
5691 // Establish two client sessions to test with.
5692 bssl::UniquePtr<SSL_SESSION> session1 =
5693 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5694 ASSERT_TRUE(session1);
5695 bssl::UniquePtr<SSL_SESSION> session2 =
5696 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5697 ASSERT_TRUE(session2);
5698
5699 auto connect_with_session = [&](SSL_SESSION *session) {
5700 ClientConfig config;
5701 config.session = session;
5702 UniquePtr<SSL> client, server;
5703 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5704 server_ctx_.get(), config));
5705 };
5706
5707 // Resume sessions in parallel with establishing new ones.
5708 {
5709 std::vector<std::thread> threads;
5710 threads.emplace_back([&] { connect_with_session(nullptr); });
5711 threads.emplace_back([&] { connect_with_session(nullptr); });
5712 threads.emplace_back([&] { connect_with_session(session1.get()); });
5713 threads.emplace_back([&] { connect_with_session(session1.get()); });
5714 threads.emplace_back([&] { connect_with_session(session2.get()); });
5715 threads.emplace_back([&] { connect_with_session(session2.get()); });
5716 for (auto &thread : threads) {
5717 thread.join();
5718 }
5719 }
5720 }
5721}
5722
5723// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5724TEST(SSLTest, GetCertificateThreads) {
5725 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5726 ASSERT_TRUE(ctx);
5727 bssl::UniquePtr<X509> cert = GetTestCertificate();
5728 ASSERT_TRUE(cert);
5729 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5730
5731 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5732 // threads concurrently. It originally was an immutable operation. Now we
5733 // implement it with a thread-safe cache, so it is worth testing.
5734 X509 *cert2_thread;
5735 std::thread thread(
5736 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5737 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5738 thread.join();
5739
5740 EXPECT_EQ(cert2, cert2_thread);
5741 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5742}
David Benjamin4cce9552018-12-13 12:20:54 -06005743
5744// Functions which access properties on the negotiated session are thread-safe
5745// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5746// performing stateful resumption will share an underlying SSL_SESSION object,
5747// potentially across threads.
5748TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5749 if (version() == TLS1_3_VERSION) {
5750 // Our TLS 1.3 implementation does not support stateful resumption.
5751 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5752 return;
5753 }
5754
5755 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5756 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5757 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5758
5759 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5760 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5761
5762 // Configure mutual authentication, so we have more session state.
5763 SSL_CTX_set_custom_verify(
5764 client_ctx_.get(), SSL_VERIFY_PEER,
5765 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5766 SSL_CTX_set_custom_verify(
5767 server_ctx_.get(), SSL_VERIFY_PEER,
5768 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5769
5770 // Establish a client session to test with.
5771 bssl::UniquePtr<SSL_SESSION> session =
5772 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5773 ASSERT_TRUE(session);
5774
5775 // Resume with it twice.
5776 UniquePtr<SSL> ssls[4];
5777 ClientConfig config;
5778 config.session = session.get();
5779 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5780 server_ctx_.get(), config));
5781 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5782 server_ctx_.get(), config));
5783
5784 // Read properties in parallel.
5785 auto read_properties = [](const SSL *ssl) {
5786 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5787 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5788 EXPECT_TRUE(peer);
5789 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5790 EXPECT_TRUE(SSL_get_curve_id(ssl));
5791 };
5792
5793 std::vector<std::thread> threads;
5794 for (const auto &ssl_ptr : ssls) {
5795 const SSL *ssl = ssl_ptr.get();
5796 threads.emplace_back([=] { read_properties(ssl); });
5797 }
5798 for (auto &thread : threads) {
5799 thread.join();
5800 }
5801}
David Benjamina486c6c2019-03-28 18:32:38 -05005802#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005803
Steven Valdezc8e0f902018-07-14 11:23:01 -04005804constexpr size_t kNumQUICLevels = 4;
5805static_assert(ssl_encryption_initial < kNumQUICLevels,
5806 "kNumQUICLevels is wrong");
5807static_assert(ssl_encryption_early_data < kNumQUICLevels,
5808 "kNumQUICLevels is wrong");
5809static_assert(ssl_encryption_handshake < kNumQUICLevels,
5810 "kNumQUICLevels is wrong");
5811static_assert(ssl_encryption_application < kNumQUICLevels,
5812 "kNumQUICLevels is wrong");
5813
David Benjamin1e859052020-02-09 16:04:58 -05005814const char *LevelToString(ssl_encryption_level_t level) {
5815 switch (level) {
5816 case ssl_encryption_initial:
5817 return "initial";
5818 case ssl_encryption_early_data:
5819 return "early data";
5820 case ssl_encryption_handshake:
5821 return "handshake";
5822 case ssl_encryption_application:
5823 return "application";
5824 }
5825 return "<unknown>";
5826}
5827
Steven Valdezc8e0f902018-07-14 11:23:01 -04005828class MockQUICTransport {
5829 public:
David Benjamind6343572019-08-15 17:29:02 -04005830 enum class Role { kClient, kServer };
5831
5832 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005833 // The caller is expected to configure initial secrets.
5834 levels_[ssl_encryption_initial].write_secret = {1};
5835 levels_[ssl_encryption_initial].read_secret = {1};
5836 }
5837
5838 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5839
5840 bool has_alert() const { return has_alert_; }
5841 ssl_encryption_level_t alert_level() const { return alert_level_; }
5842 uint8_t alert() const { return alert_; }
5843
5844 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5845 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005846 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5847 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005848 }
5849
David Benjamin1e859052020-02-09 16:04:58 -05005850 bool HasReadSecret(ssl_encryption_level_t level) const {
5851 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005852 }
5853
David Benjamin1e859052020-02-09 16:04:58 -05005854 bool HasWriteSecret(ssl_encryption_level_t level) const {
5855 return !levels_[level].write_secret.empty();
5856 }
5857
David Benjamin5298ef92020-03-13 12:17:30 -04005858 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5859
David Benjamin1e859052020-02-09 16:04:58 -05005860 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5861 Span<const uint8_t> secret) {
5862 if (HasReadSecret(level)) {
5863 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5864 return false;
5865 }
5866
5867 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5868 ADD_FAILURE() << "Unexpected early data read secret";
5869 return false;
5870 }
5871
5872 ssl_encryption_level_t ack_level =
5873 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5874 if (!HasWriteSecret(ack_level)) {
5875 ADD_FAILURE() << LevelToString(level)
5876 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005877 return false;
5878 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005879
5880 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005881 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005882 return false;
5883 }
5884
David Benjamin1e859052020-02-09 16:04:58 -05005885 if (level != ssl_encryption_early_data &&
5886 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5887 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005888 return false;
5889 }
David Benjamind6343572019-08-15 17:29:02 -04005890
David Benjamin1e859052020-02-09 16:04:58 -05005891 levels_[level].read_secret.assign(secret.begin(), secret.end());
5892 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5893 return true;
5894 }
5895
5896 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5897 Span<const uint8_t> secret) {
5898 if (HasWriteSecret(level)) {
5899 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005900 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005901 }
David Benjamind6343572019-08-15 17:29:02 -04005902
David Benjamin1e859052020-02-09 16:04:58 -05005903 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5904 ADD_FAILURE() << "Unexpected early data write secret";
5905 return false;
5906 }
5907
5908 if (cipher == nullptr) {
5909 ADD_FAILURE() << "Unexpected null cipher";
5910 return false;
5911 }
5912
5913 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005914 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005915 return true;
5916 }
5917
5918 bool WriteHandshakeData(ssl_encryption_level_t level,
5919 Span<const uint8_t> data) {
5920 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005921 ADD_FAILURE() << LevelToString(level)
5922 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005923 return false;
5924 }
David Benjamin5298ef92020-03-13 12:17:30 -04005925
5926 // Although the levels are conceptually separate, BoringSSL finishes writing
5927 // data from a previous level before installing keys for the next level.
5928 if (!allow_out_of_order_writes_) {
5929 switch (level) {
5930 case ssl_encryption_early_data:
5931 ADD_FAILURE() << "unexpected handshake data at early data level";
5932 return false;
5933 case ssl_encryption_initial:
5934 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5935 ADD_FAILURE()
5936 << LevelToString(level)
5937 << " handshake data written after handshake keys installed";
5938 return false;
5939 }
5940 OPENSSL_FALLTHROUGH;
5941 case ssl_encryption_handshake:
5942 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5943 ADD_FAILURE()
5944 << LevelToString(level)
5945 << " handshake data written after application keys installed";
5946 return false;
5947 }
5948 OPENSSL_FALLTHROUGH;
5949 case ssl_encryption_application:
5950 break;
5951 }
5952 }
5953
Steven Valdezc8e0f902018-07-14 11:23:01 -04005954 levels_[level].write_data.insert(levels_[level].write_data.end(),
5955 data.begin(), data.end());
5956 return true;
5957 }
5958
5959 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5960 if (has_alert_) {
5961 ADD_FAILURE() << "duplicate alert sent";
5962 return false;
5963 }
5964
5965 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005966 ADD_FAILURE() << LevelToString(level)
5967 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005968 return false;
5969 }
5970
5971 has_alert_ = true;
5972 alert_level_ = level;
5973 alert_ = alert_value;
5974 return true;
5975 }
5976
5977 bool ReadHandshakeData(std::vector<uint8_t> *out,
5978 ssl_encryption_level_t level,
5979 size_t num = std::numeric_limits<size_t>::max()) {
5980 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005981 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005982 return false;
5983 }
5984 // The peer may not have configured any keys yet.
5985 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005986 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005987 return true;
5988 }
5989 // Check the peer computed the same key.
5990 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005991 ADD_FAILURE() << "peer write key does not match read key in level "
5992 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005993 return false;
5994 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005995 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005996 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005997 return false;
5998 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005999 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
6000 num = std::min(num, peer_data->size());
6001 out->assign(peer_data->begin(), peer_data->begin() + num);
6002 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
6003 return true;
6004 }
6005
6006 private:
David Benjamind6343572019-08-15 17:29:02 -04006007 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006008 MockQUICTransport *peer_ = nullptr;
6009
David Benjamin5298ef92020-03-13 12:17:30 -04006010 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006011 bool has_alert_ = false;
6012 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
6013 uint8_t alert_ = 0;
6014
6015 struct Level {
6016 std::vector<uint8_t> write_data;
6017 std::vector<uint8_t> write_secret;
6018 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05006019 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006020 };
6021 Level levels_[kNumQUICLevels];
6022};
6023
6024class MockQUICTransportPair {
6025 public:
David Benjamind6343572019-08-15 17:29:02 -04006026 MockQUICTransportPair()
6027 : client_(MockQUICTransport::Role::kClient),
6028 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006029 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04006030 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006031 }
6032
6033 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006034 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04006035 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006036 }
6037
6038 MockQUICTransport *client() { return &client_; }
6039 MockQUICTransport *server() { return &server_; }
6040
6041 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05006042 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
6043 // |PeerSecretsMatch| checks that |server_| is analogously configured.
6044 return client_.PeerSecretsMatch(level) &&
6045 client_.HasWriteSecret(level) &&
6046 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006047 }
6048
6049 private:
6050 MockQUICTransport client_;
6051 MockQUICTransport server_;
6052};
6053
6054class QUICMethodTest : public testing::Test {
6055 protected:
6056 void SetUp() override {
6057 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006058 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006059 ASSERT_TRUE(client_ctx_);
6060 ASSERT_TRUE(server_ctx_);
6061
Steven Valdezc8e0f902018-07-14 11:23:01 -04006062 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6063 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6064 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
6065 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07006066
6067 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
6068 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
6069 sizeof(kALPNProtos)),
6070 0);
6071 SSL_CTX_set_alpn_select_cb(
6072 server_ctx_.get(),
6073 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6074 unsigned in_len, void *arg) -> int {
6075 return SSL_select_next_proto(
6076 const_cast<uint8_t **>(out), out_len, in, in_len,
6077 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
6078 ? SSL_TLSEXT_ERR_OK
6079 : SSL_TLSEXT_ERR_NOACK;
6080 },
6081 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006082 }
6083
6084 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
6085 return ex_data_.Get(ssl);
6086 }
6087
6088 static bool ProvideHandshakeData(
6089 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
6090 MockQUICTransport *transport = TransportFromSSL(ssl);
6091 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
6092 std::vector<uint8_t> data;
6093 return transport->ReadHandshakeData(&data, level, num) &&
6094 SSL_provide_quic_data(ssl, level, data.data(), data.size());
6095 }
6096
David Benjamin5298ef92020-03-13 12:17:30 -04006097 void AllowOutOfOrderWrites() {
6098 allow_out_of_order_writes_ = true;
6099 }
6100
Steven Valdezc8e0f902018-07-14 11:23:01 -04006101 bool CreateClientAndServer() {
6102 client_.reset(SSL_new(client_ctx_.get()));
6103 server_.reset(SSL_new(server_ctx_.get()));
6104 if (!client_ || !server_) {
6105 return false;
6106 }
6107
6108 SSL_set_connect_state(client_.get());
6109 SSL_set_accept_state(server_.get());
6110
David Benjamind6343572019-08-15 17:29:02 -04006111 transport_.reset(new MockQUICTransportPair);
6112 ex_data_.Set(client_.get(), transport_->client());
6113 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04006114 if (allow_out_of_order_writes_) {
6115 transport_->client()->AllowOutOfOrderWrites();
6116 transport_->server()->AllowOutOfOrderWrites();
6117 }
Nick Harper7c522992020-04-30 14:15:49 -07006118 static const uint8_t client_transport_params[] = {0};
6119 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
6120 sizeof(client_transport_params)) ||
6121 !SSL_set_quic_transport_params(server_.get(),
6122 server_transport_params_.data(),
6123 server_transport_params_.size()) ||
6124 !SSL_set_quic_early_data_context(
6125 server_.get(), server_quic_early_data_context_.data(),
6126 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07006127 return false;
6128 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006129 return true;
6130 }
6131
Nick Harper72cff812020-03-26 18:06:16 -07006132 enum class ExpectedError {
6133 kNoError,
6134 kClientError,
6135 kServerError,
6136 };
6137
David Benjamind6343572019-08-15 17:29:02 -04006138 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
6139 // |server_| until each completes once. It returns true on success and false
6140 // on failure.
6141 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07006142 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
6143 }
6144
6145 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
6146 // once. If |expect_client_error| is true, it will return true only if the
6147 // client handshake failed. Otherwise, it returns true if both handshakes
6148 // succeed and false otherwise.
6149 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04006150 bool client_done = false, server_done = false;
6151 while (!client_done || !server_done) {
6152 if (!client_done) {
6153 if (!ProvideHandshakeData(client_.get())) {
6154 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
6155 return false;
6156 }
6157 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006158 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04006159 if (client_ret == 1) {
6160 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006161 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006162 if (expected_error == ExpectedError::kClientError) {
6163 return true;
6164 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006165 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
6166 << client_err;
6167 return false;
David Benjamind6343572019-08-15 17:29:02 -04006168 }
6169 }
6170
6171 if (!server_done) {
6172 if (!ProvideHandshakeData(server_.get())) {
6173 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
6174 return false;
6175 }
6176 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006177 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04006178 if (server_ret == 1) {
6179 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006180 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006181 if (expected_error == ExpectedError::kServerError) {
6182 return true;
6183 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006184 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
6185 << server_err;
6186 return false;
David Benjamind6343572019-08-15 17:29:02 -04006187 }
6188 }
6189 }
Nick Harper72cff812020-03-26 18:06:16 -07006190 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04006191 }
6192
6193 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
6194 g_last_session = nullptr;
6195 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6196 if (!CreateClientAndServer() ||
6197 !CompleteHandshakesForQUIC()) {
6198 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006199 }
6200
David Benjamind6343572019-08-15 17:29:02 -04006201 // The server sent NewSessionTicket messages in the handshake.
6202 if (!ProvideHandshakeData(client_.get()) ||
6203 !SSL_process_quic_post_handshake(client_.get())) {
6204 return nullptr;
6205 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006206
David Benjamind6343572019-08-15 17:29:02 -04006207 return std::move(g_last_session);
6208 }
6209
6210 void ExpectHandshakeSuccess() {
6211 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6212 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
6213 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
6214 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
6215 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
6216 EXPECT_FALSE(transport_->client()->has_alert());
6217 EXPECT_FALSE(transport_->server()->has_alert());
6218
6219 // SSL_do_handshake is now idempotent.
6220 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6221 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006222 }
6223
David Benjamin1e859052020-02-09 16:04:58 -05006224 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
6225 // the test.
6226 SSL_QUIC_METHOD DefaultQUICMethod() {
6227 return SSL_QUIC_METHOD{
6228 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
6229 FlushFlightCallback, SendAlertCallback,
6230 };
6231 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006232
David Benjamin1e859052020-02-09 16:04:58 -05006233 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6234 const SSL_CIPHER *cipher,
6235 const uint8_t *secret, size_t secret_len) {
6236 return TransportFromSSL(ssl)->SetReadSecret(
6237 level, cipher, MakeConstSpan(secret, secret_len));
6238 }
6239
6240 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6241 const SSL_CIPHER *cipher,
6242 const uint8_t *secret, size_t secret_len) {
6243 return TransportFromSSL(ssl)->SetWriteSecret(
6244 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006245 }
6246
David Benjamincc9d9352018-10-30 19:45:22 -05006247 static int AddHandshakeDataCallback(SSL *ssl,
6248 enum ssl_encryption_level_t level,
6249 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006250 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6251 return TransportFromSSL(ssl)->WriteHandshakeData(level,
6252 MakeConstSpan(data, len));
6253 }
6254
6255 static int FlushFlightCallback(SSL *ssl) { return 1; }
6256
6257 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6258 uint8_t alert) {
6259 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6260 return TransportFromSSL(ssl)->SendAlert(level, alert);
6261 }
6262
6263 bssl::UniquePtr<SSL_CTX> client_ctx_;
6264 bssl::UniquePtr<SSL_CTX> server_ctx_;
6265
6266 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04006267 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006268
6269 bssl::UniquePtr<SSL> client_;
6270 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04006271
Nick Harper7c522992020-04-30 14:15:49 -07006272 std::vector<uint8_t> server_transport_params_ = {1};
6273 std::vector<uint8_t> server_quic_early_data_context_ = {2};
6274
David Benjamin5298ef92020-03-13 12:17:30 -04006275 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006276};
6277
6278UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6279
David Benjaminfd863b62019-07-25 13:51:32 -04006280// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006281TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05006282 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006283
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006284 g_last_session = nullptr;
6285
6286 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6287 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006288 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));
David Benjamind6343572019-08-15 17:29:02 -04006290
Steven Valdezc8e0f902018-07-14 11:23:01 -04006291 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006292 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006293
David Benjamind6343572019-08-15 17:29:02 -04006294 ExpectHandshakeSuccess();
6295 EXPECT_FALSE(SSL_session_reused(client_.get()));
6296 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006297
6298 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006299 EXPECT_FALSE(g_last_session);
6300 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6301 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6302 EXPECT_TRUE(g_last_session);
6303
6304 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04006305 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006306 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6307 SSL_set_session(client_.get(), session.get());
6308
David Benjamind6343572019-08-15 17:29:02 -04006309 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006310
David Benjamind6343572019-08-15 17:29:02 -04006311 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006312 EXPECT_TRUE(SSL_session_reused(client_.get()));
6313 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006314}
6315
David Benjaminfd863b62019-07-25 13:51:32 -04006316// Test that HelloRetryRequest in QUIC works.
6317TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006318 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006319
6320 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6321 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6322
6323 // BoringSSL predicts the most preferred curve, so using different preferences
6324 // will trigger HelloRetryRequest.
6325 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6326 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
6327 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6328 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6329 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
6330 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6331
6332 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006333 ASSERT_TRUE(CompleteHandshakesForQUIC());
6334 ExpectHandshakeSuccess();
6335}
David Benjaminfd863b62019-07-25 13:51:32 -04006336
Nick Harpere32549e2020-05-06 14:27:11 -07006337// Test that the client does not send a legacy_session_id in the ClientHello.
6338TEST_F(QUICMethodTest, NoLegacySessionId) {
6339 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6340
6341 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6342 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6343 // Check that the session ID length is 0 in an early callback.
6344 SSL_CTX_set_select_certificate_cb(
6345 server_ctx_.get(),
6346 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6347 EXPECT_EQ(client_hello->session_id_len, 0u);
6348 return ssl_select_cert_success;
6349 });
6350
6351 ASSERT_TRUE(CreateClientAndServer());
6352 ASSERT_TRUE(CompleteHandshakesForQUIC());
6353
6354 ExpectHandshakeSuccess();
6355}
6356
David Benjamin1e859052020-02-09 16:04:58 -05006357// Test that, even in a 1-RTT handshake, the server installs keys at the right
6358// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6359TEST_F(QUICMethodTest, HalfRTTKeys) {
6360 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6361
6362 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6363 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6364 ASSERT_TRUE(CreateClientAndServer());
6365
6366 // The client sends ClientHello.
6367 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6368 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6369
6370 // The server reads ClientHello and sends ServerHello..Finished.
6371 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6372 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6373 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6374
6375 // At this point, the server has half-RTT write keys, but it cannot access
6376 // 1-RTT read keys until client Finished.
6377 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6378 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6379
6380 // Finish up the client and server handshakes.
6381 ASSERT_TRUE(CompleteHandshakesForQUIC());
6382
6383 // Both sides can now exchange 1-RTT data.
6384 ExpectHandshakeSuccess();
6385}
6386
David Benjamind6343572019-08-15 17:29:02 -04006387TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006388 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006389
6390 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6391 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6392 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6393 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6394 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6395
6396 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6397 ASSERT_TRUE(session);
6398
6399 ASSERT_TRUE(CreateClientAndServer());
6400 SSL_set_session(client_.get(), session.get());
6401
6402 // The client handshake should return immediately into the early data state.
6403 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6404 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6405 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006406 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006407
6408 // The server will consume the ClientHello and also enter the early data
6409 // state.
6410 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6411 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6412 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6413 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006414 // At this point, the server has half-RTT write keys, but it cannot access
6415 // 1-RTT read keys until client Finished.
6416 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6417 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006418
6419 // Finish up the client and server handshakes.
6420 ASSERT_TRUE(CompleteHandshakesForQUIC());
6421
6422 // Both sides can now exchange 1-RTT data.
6423 ExpectHandshakeSuccess();
6424 EXPECT_TRUE(SSL_session_reused(client_.get()));
6425 EXPECT_TRUE(SSL_session_reused(server_.get()));
6426 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6427 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6428 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6429 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006430
6431 // Finish handling post-handshake messages after the first 0-RTT resumption.
6432 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6433 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6434
6435 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6436 // accepted again.
6437 ASSERT_TRUE(CreateClientAndServer());
6438 SSL_set_session(client_.get(), g_last_session.get());
6439
6440 // The client handshake should return immediately into the early data state.
6441 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6442 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6443 // The transport should have keys for sending 0-RTT data.
6444 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6445
6446 // The server will consume the ClientHello and also enter the early data
6447 // state.
6448 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6449 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6450 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6451 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6452 // At this point, the server has half-RTT write keys, but it cannot access
6453 // 1-RTT read keys until client Finished.
6454 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6455 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6456
6457 // Finish up the client and server handshakes.
6458 ASSERT_TRUE(CompleteHandshakesForQUIC());
6459
6460 // Both sides can now exchange 1-RTT data.
6461 ExpectHandshakeSuccess();
6462 EXPECT_TRUE(SSL_session_reused(client_.get()));
6463 EXPECT_TRUE(SSL_session_reused(server_.get()));
6464 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6465 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6466 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6467 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6468 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6469 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006470}
6471
Nick Harper7c522992020-04-30 14:15:49 -07006472TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6473 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6474
6475 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6476 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6477 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6478 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6479 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6480
6481
6482 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6483 ASSERT_TRUE(session);
6484
Nick Harper85194322020-05-20 16:59:29 -07006485 ASSERT_TRUE(CreateClientAndServer());
6486 static const uint8_t new_context[] = {4};
6487 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6488 sizeof(new_context)));
6489 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006490
Nick Harper85194322020-05-20 16:59:29 -07006491 // The client handshake should return immediately into the early data
6492 // state.
6493 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6494 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6495 // The transport should have keys for sending 0-RTT data.
6496 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006497
Nick Harper85194322020-05-20 16:59:29 -07006498 // The server will consume the ClientHello, but it will not accept 0-RTT.
6499 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6500 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6501 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6502 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6503 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006504
Nick Harper85194322020-05-20 16:59:29 -07006505 // The client consumes the server response and signals 0-RTT rejection.
6506 for (;;) {
6507 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6508 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6509 int err = SSL_get_error(client_.get(), -1);
6510 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6511 break;
Nick Harper7c522992020-04-30 14:15:49 -07006512 }
Nick Harper85194322020-05-20 16:59:29 -07006513 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006514 }
Nick Harper85194322020-05-20 16:59:29 -07006515
6516 // As in TLS over TCP, 0-RTT rejection is sticky.
6517 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6518 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6519
6520 // Finish up the client and server handshakes.
6521 SSL_reset_early_data_reject(client_.get());
6522 ASSERT_TRUE(CompleteHandshakesForQUIC());
6523
6524 // Both sides can now exchange 1-RTT data.
6525 ExpectHandshakeSuccess();
6526 EXPECT_TRUE(SSL_session_reused(client_.get()));
6527 EXPECT_TRUE(SSL_session_reused(server_.get()));
6528 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6529 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6530 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6531 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6532}
6533
6534TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6535 server_quic_early_data_context_ = {};
6536 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6537
6538 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6539 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6540 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6541 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6542 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6543
6544 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6545 ASSERT_TRUE(session);
6546 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006547}
6548
David Benjamind6343572019-08-15 17:29:02 -04006549TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006550 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006551
6552 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6553 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6554 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6555 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6556 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6557
6558 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6559 ASSERT_TRUE(session);
6560
6561 for (bool reject_hrr : {false, true}) {
6562 SCOPED_TRACE(reject_hrr);
6563
6564 ASSERT_TRUE(CreateClientAndServer());
6565 if (reject_hrr) {
6566 // Configure the server to prefer P-256, which will reject 0-RTT via
6567 // HelloRetryRequest.
6568 int p256 = NID_X9_62_prime256v1;
6569 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6570 } else {
6571 // Disable 0-RTT on the server, so it will reject it.
6572 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006573 }
David Benjamind6343572019-08-15 17:29:02 -04006574 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006575
David Benjamind6343572019-08-15 17:29:02 -04006576 // The client handshake should return immediately into the early data state.
6577 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6578 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6579 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006580 EXPECT_TRUE(
6581 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006582
6583 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006584 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006585 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6586 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6587 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006588 EXPECT_FALSE(
6589 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006590
6591 // The client consumes the server response and signals 0-RTT rejection.
6592 for (;;) {
6593 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6594 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6595 int err = SSL_get_error(client_.get(), -1);
6596 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6597 break;
6598 }
6599 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006600 }
6601
David Benjamind6343572019-08-15 17:29:02 -04006602 // As in TLS over TCP, 0-RTT rejection is sticky.
6603 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6604 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6605
6606 // Finish up the client and server handshakes.
6607 SSL_reset_early_data_reject(client_.get());
6608 ASSERT_TRUE(CompleteHandshakesForQUIC());
6609
6610 // Both sides can now exchange 1-RTT data.
6611 ExpectHandshakeSuccess();
6612 EXPECT_TRUE(SSL_session_reused(client_.get()));
6613 EXPECT_TRUE(SSL_session_reused(server_.get()));
6614 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6615 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6616 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6617 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006618 }
David Benjaminfd863b62019-07-25 13:51:32 -04006619}
6620
David Benjaminee0716f2019-11-19 14:16:28 +08006621TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006622 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006623
6624 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6625 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6626 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6627 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6628 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6629 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6630
6631 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6632 ASSERT_TRUE(session);
6633
6634 ASSERT_TRUE(CreateClientAndServer());
6635 SSL_set_session(client_.get(), session.get());
6636
6637 // Configure the certificate (re)verification to never complete. The client
6638 // handshake should pause.
6639 SSL_set_custom_verify(
6640 client_.get(), SSL_VERIFY_PEER,
6641 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6642 return ssl_verify_retry;
6643 });
6644 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6645 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6646 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6647
6648 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006649 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006650
6651 // After the verification completes, the handshake progresses to the 0-RTT
6652 // point and releases keys.
6653 SSL_set_custom_verify(
6654 client_.get(), SSL_VERIFY_PEER,
6655 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6656 return ssl_verify_ok;
6657 });
6658 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6659 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006660 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006661}
6662
Steven Valdezc8e0f902018-07-14 11:23:01 -04006663// Test only releasing data to QUIC one byte at a time on request, to maximize
6664// state machine pauses. Additionally, test that existing asynchronous callbacks
6665// still work.
6666TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006667 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006668
6669 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6670 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6671 ASSERT_TRUE(CreateClientAndServer());
6672
6673 // Install an asynchronous certificate callback.
6674 bool cert_cb_ok = false;
6675 SSL_set_cert_cb(server_.get(),
6676 [](SSL *, void *arg) -> int {
6677 return *static_cast<bool *>(arg) ? 1 : -1;
6678 },
6679 &cert_cb_ok);
6680
6681 for (;;) {
6682 int client_ret = SSL_do_handshake(client_.get());
6683 if (client_ret != 1) {
6684 ASSERT_EQ(client_ret, -1);
6685 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6686 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6687 }
6688
6689 int server_ret = SSL_do_handshake(server_.get());
6690 if (server_ret != 1) {
6691 ASSERT_EQ(server_ret, -1);
6692 int ssl_err = SSL_get_error(server_.get(), server_ret);
6693 switch (ssl_err) {
6694 case SSL_ERROR_WANT_READ:
6695 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6696 break;
6697 case SSL_ERROR_WANT_X509_LOOKUP:
6698 ASSERT_FALSE(cert_cb_ok);
6699 cert_cb_ok = true;
6700 break;
6701 default:
6702 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6703 }
6704 }
6705
6706 if (client_ret == 1 && server_ret == 1) {
6707 break;
6708 }
6709 }
6710
David Benjamind6343572019-08-15 17:29:02 -04006711 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006712}
6713
6714// Test buffering write data until explicit flushes.
6715TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006716 AllowOutOfOrderWrites();
6717
Steven Valdezc8e0f902018-07-14 11:23:01 -04006718 struct BufferedFlight {
6719 std::vector<uint8_t> data[kNumQUICLevels];
6720 };
6721 static UnownedSSLExData<BufferedFlight> buffered_flights;
6722
David Benjamincc9d9352018-10-30 19:45:22 -05006723 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6724 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006725 BufferedFlight *flight = buffered_flights.Get(ssl);
6726 flight->data[level].insert(flight->data[level].end(), data, data + len);
6727 return 1;
6728 };
6729
6730 auto flush_flight = [](SSL *ssl) -> int {
6731 BufferedFlight *flight = buffered_flights.Get(ssl);
6732 for (size_t level = 0; level < kNumQUICLevels; level++) {
6733 if (!flight->data[level].empty()) {
6734 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6735 static_cast<ssl_encryption_level_t>(level),
6736 flight->data[level])) {
6737 return 0;
6738 }
6739 flight->data[level].clear();
6740 }
6741 }
6742 return 1;
6743 };
6744
David Benjamin1e859052020-02-09 16:04:58 -05006745 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6746 quic_method.add_handshake_data = add_handshake_data;
6747 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006748
6749 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6750 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6751 ASSERT_TRUE(CreateClientAndServer());
6752
6753 BufferedFlight client_flight, server_flight;
6754 buffered_flights.Set(client_.get(), &client_flight);
6755 buffered_flights.Set(server_.get(), &server_flight);
6756
David Benjamind6343572019-08-15 17:29:02 -04006757 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006758
David Benjamind6343572019-08-15 17:29:02 -04006759 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006760}
6761
6762// Test that excess data at one level is rejected. That is, if a single
6763// |SSL_provide_quic_data| call included both ServerHello and
6764// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6765// key change.
6766TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006767 AllowOutOfOrderWrites();
6768
David Benjamincc9d9352018-10-30 19:45:22 -05006769 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6770 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006771 // Switch everything to the initial level.
6772 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6773 MakeConstSpan(data, len));
6774 };
6775
David Benjamin1e859052020-02-09 16:04:58 -05006776 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6777 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006778
6779 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6780 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6781 ASSERT_TRUE(CreateClientAndServer());
6782
6783 // Send the ClientHello and ServerHello through Finished.
6784 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6785 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6786 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6787 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6788 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6789
6790 // The client is still waiting for the ServerHello at initial
6791 // encryption.
6792 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6793
David Benjamincc9d9352018-10-30 19:45:22 -05006794 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6795 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006796 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6797
6798 // The client reads ServerHello successfully, but then rejects the buffered
6799 // EncryptedExtensions on key change.
6800 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6801 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6802 uint32_t err = ERR_get_error();
6803 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006804 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006805
David Benjamin1e859052020-02-09 16:04:58 -05006806 // The client sends an alert in response to this. The alert is sent at
6807 // handshake level because we install write secrets before read secrets and
6808 // the error is discovered when installing the read secret. (How to send
6809 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006810 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006811 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006812 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006813
David Benjamin5298ef92020-03-13 12:17:30 -04006814 // Sanity-check handshake secrets. The error is discovered while setting the
6815 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006816 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006817 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006818}
6819
6820// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6821TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006822 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006823
6824 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6825 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6826 ASSERT_TRUE(CreateClientAndServer());
6827
6828 // Send the ClientHello and ServerHello through Finished.
6829 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6830 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6831 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6832 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6833 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6834
6835 // The client is still waiting for the ServerHello at initial
6836 // encryption.
6837 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6838
6839 // Data cannot be provided at the next level.
6840 std::vector<uint8_t> data;
6841 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006842 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006843 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6844 data.data(), data.size()));
6845 ERR_clear_error();
6846
6847 // Progress to EncryptedExtensions.
6848 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6849 data.data(), data.size()));
6850 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6851 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6852 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6853
6854 // Data cannot be provided at the previous level.
6855 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006856 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006857 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6858 data.data(), data.size()));
6859}
6860
6861TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006862 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006863
6864 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6865 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6866 ASSERT_TRUE(CreateClientAndServer());
6867
6868 size_t limit =
6869 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6870 uint8_t b = 0;
6871 for (size_t i = 0; i < limit; i++) {
6872 ASSERT_TRUE(
6873 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6874 }
6875
6876 EXPECT_FALSE(
6877 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6878}
6879
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006880// Provide invalid post-handshake data.
6881TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006882 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006883
6884 g_last_session = nullptr;
6885
6886 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6887 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6888 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6889 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6890 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006891 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006892
6893 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6894 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006895 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6896 EXPECT_FALSE(transport_->client()->has_alert());
6897 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006898
6899 // Junk sent as part of post-handshake data should cause an error.
6900 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6901 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6902 kJunk, sizeof(kJunk)));
6903 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6904}
6905
Nick Harper80ddfc72020-03-11 18:26:31 -07006906static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6907 Span<const uint8_t> expected) {
6908 const uint8_t *received;
6909 size_t received_len;
6910 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6911 ASSERT_EQ(received_len, expected.size());
6912 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6913}
6914
6915TEST_F(QUICMethodTest, SetTransportParameters) {
6916 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6917 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6918 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6919
6920 ASSERT_TRUE(CreateClientAndServer());
6921 uint8_t kClientParams[] = {1, 2, 3, 4};
6922 uint8_t kServerParams[] = {5, 6, 7};
6923 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6924 sizeof(kClientParams)));
6925 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6926 sizeof(kServerParams)));
6927
6928 ASSERT_TRUE(CompleteHandshakesForQUIC());
6929 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6930 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6931}
6932
6933TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6934 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6935 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6936 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6937
6938 ASSERT_TRUE(CreateClientAndServer());
6939 uint8_t kClientParams[] = {1, 2, 3, 4};
6940 static uint8_t kServerParams[] = {5, 6, 7};
6941 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6942 sizeof(kClientParams)));
6943 SSL_CTX_set_tlsext_servername_callback(
6944 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6945 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6946 sizeof(kServerParams)));
6947 return SSL_TLSEXT_ERR_OK;
6948 });
6949
6950 ASSERT_TRUE(CompleteHandshakesForQUIC());
6951 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6952 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6953}
6954
Nick Harper6bfd25c2020-03-30 17:15:19 -07006955TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6956 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6957
6958 g_last_session = nullptr;
6959
6960 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6961 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6962 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6963 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6964
6965 ASSERT_TRUE(CreateClientAndServer());
6966 ASSERT_TRUE(CompleteHandshakesForQUIC());
6967
6968 ExpectHandshakeSuccess();
6969 EXPECT_FALSE(SSL_session_reused(client_.get()));
6970 EXPECT_FALSE(SSL_session_reused(server_.get()));
6971
6972 // The server sent NewSessionTicket messages in the handshake.
6973 EXPECT_FALSE(g_last_session);
6974 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6975 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6976 EXPECT_TRUE(g_last_session);
6977
6978 // Pretend that g_last_session came from a TLS-over-TCP connection.
6979 g_last_session.get()->is_quic = false;
6980
6981 // Create a second connection and verify that resumption does not occur with
6982 // a session from a non-QUIC connection. This tests that the client does not
6983 // offer over QUIC a session believed to be received over TCP. The server
6984 // believes this is a QUIC session, so if the client offered the session, the
6985 // server would have resumed it.
6986 ASSERT_TRUE(CreateClientAndServer());
6987 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6988 SSL_set_session(client_.get(), session.get());
6989
6990 ASSERT_TRUE(CompleteHandshakesForQUIC());
6991 ExpectHandshakeSuccess();
6992 EXPECT_FALSE(SSL_session_reused(client_.get()));
6993 EXPECT_FALSE(SSL_session_reused(server_.get()));
6994}
6995
6996TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6997 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6998
6999 g_last_session = nullptr;
7000
7001 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7002 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7003 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7004 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7005
7006 ASSERT_TRUE(CreateClientAndServer());
7007 ASSERT_TRUE(CompleteHandshakesForQUIC());
7008
7009 ExpectHandshakeSuccess();
7010 EXPECT_FALSE(SSL_session_reused(client_.get()));
7011 EXPECT_FALSE(SSL_session_reused(server_.get()));
7012
7013 // The server sent NewSessionTicket messages in the handshake.
7014 EXPECT_FALSE(g_last_session);
7015 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7016 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
7017 EXPECT_TRUE(g_last_session);
7018
7019 // Attempt a resumption with g_last_session using TLS_method.
7020 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
7021 ASSERT_TRUE(client_ctx);
7022
7023 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
7024
7025 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
7026 server(SSL_new(server_ctx_.get()));
7027 ASSERT_TRUE(client);
7028 ASSERT_TRUE(server);
7029 SSL_set_connect_state(client.get());
7030 SSL_set_accept_state(server.get());
7031
7032 // The TLS-over-TCP client will refuse to resume with a quic session, so
7033 // mark is_quic = false to bypass the client check to test the server check.
7034 g_last_session.get()->is_quic = false;
7035 SSL_set_session(client.get(), g_last_session.get());
7036
7037 BIO *bio1, *bio2;
7038 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
7039
7040 // SSL_set_bio takes ownership.
7041 SSL_set_bio(client.get(), bio1, bio1);
7042 SSL_set_bio(server.get(), bio2, bio2);
7043 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7044
7045 EXPECT_FALSE(SSL_session_reused(client.get()));
7046 EXPECT_FALSE(SSL_session_reused(server.get()));
7047}
7048
Nick Harper72cff812020-03-26 18:06:16 -07007049TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
7050 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7051 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7052 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7053
7054 ASSERT_TRUE(CreateClientAndServer());
7055 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
7056 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7057}
7058
7059TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
7060 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7061 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7062 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7063
7064 ASSERT_TRUE(CreateClientAndServer());
7065 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
7066 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
7067}
7068
David Schinazi3d8b8c32021-01-14 11:25:49 -08007069TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
7070 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7071 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7072 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7073
7074 ASSERT_TRUE(CreateClientAndServer());
7075 uint8_t kClientParams[] = {1, 2, 3, 4};
7076 uint8_t kServerParams[] = {5, 6, 7};
7077 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7078 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7079 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7080 sizeof(kClientParams)));
7081 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7082 sizeof(kServerParams)));
7083
7084 ASSERT_TRUE(CompleteHandshakesForQUIC());
7085 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7086 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7087}
7088
7089TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
7090 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7091 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7092 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7093
7094 ASSERT_TRUE(CreateClientAndServer());
7095 uint8_t kClientParams[] = {1, 2, 3, 4};
7096 uint8_t kServerParams[] = {5, 6, 7};
7097 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7098 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7099 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7100 sizeof(kClientParams)));
7101 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7102 sizeof(kServerParams)));
7103
7104 ASSERT_TRUE(CompleteHandshakesForQUIC());
7105 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7106 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7107}
7108
7109TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
7110 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7111 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7112 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7113
7114 ASSERT_TRUE(CreateClientAndServer());
7115 uint8_t kClientParams[] = {1, 2, 3, 4};
7116 uint8_t kServerParams[] = {5, 6, 7};
7117 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7118 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7119 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7120 sizeof(kClientParams)));
7121 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7122 sizeof(kServerParams)));
7123
7124 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7125}
7126
7127TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
7128 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7129 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7130 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7131
7132 ASSERT_TRUE(CreateClientAndServer());
7133 uint8_t kClientParams[] = {1, 2, 3, 4};
7134 uint8_t kServerParams[] = {5, 6, 7};
7135 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7136 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7137 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7138 sizeof(kClientParams)));
7139 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7140 sizeof(kServerParams)));
7141
7142 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7143}
7144
David Benjaminc47bfce2021-01-20 17:10:32 -05007145// Test that the default QUIC code point is consistent with
7146// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
7147// update the two values together.
7148TEST_F(QUICMethodTest, QuicCodePointDefault) {
7149 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7150 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7151 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7152 SSL_CTX_set_select_certificate_cb(
7153 server_ctx_.get(),
7154 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7155 const uint8_t *data;
7156 size_t len;
7157 if (!SSL_early_callback_ctx_extension_get(
7158 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
7159 &len)) {
7160 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
7161 return ssl_select_cert_error;
7162 }
7163 return ssl_select_cert_success;
7164 });
7165
7166 ASSERT_TRUE(CreateClientAndServer());
7167 ASSERT_TRUE(CompleteHandshakesForQUIC());
7168}
7169
Adam Langley7540cc22019-04-18 09:56:13 -07007170extern "C" {
7171int BORINGSSL_enum_c_type_test(void);
7172}
7173
7174TEST(SSLTest, EnumTypes) {
7175 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
7176 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
7177}
7178
David Benjaminb29e1e12019-05-06 14:44:46 -05007179TEST_P(SSLVersionTest, DoubleSSLError) {
7180 // Connect the inner SSL connections.
7181 ASSERT_TRUE(Connect());
7182
7183 // Make a pair of |BIO|s which wrap |client_| and |server_|.
7184 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
7185 ASSERT_TRUE(bio_method);
7186 ASSERT_TRUE(BIO_meth_set_read(
7187 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
7188 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7189 int ret = SSL_read(ssl, out, len);
7190 int ssl_ret = SSL_get_error(ssl, ret);
7191 if (ssl_ret == SSL_ERROR_WANT_READ) {
7192 BIO_set_retry_read(bio);
7193 }
7194 return ret;
7195 }));
7196 ASSERT_TRUE(BIO_meth_set_write(
7197 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
7198 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7199 int ret = SSL_write(ssl, in, len);
7200 int ssl_ret = SSL_get_error(ssl, ret);
7201 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
7202 BIO_set_retry_write(bio);
7203 }
7204 return ret;
7205 }));
7206 ASSERT_TRUE(BIO_meth_set_ctrl(
7207 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
7208 // |SSL| objects require |BIO_flush| support.
7209 if (cmd == BIO_CTRL_FLUSH) {
7210 return 1;
7211 }
7212 return 0;
7213 }));
7214
7215 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
7216 ASSERT_TRUE(client_bio);
7217 BIO_set_data(client_bio.get(), client_.get());
7218 BIO_set_init(client_bio.get(), 1);
7219
7220 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
7221 ASSERT_TRUE(server_bio);
7222 BIO_set_data(server_bio.get(), server_.get());
7223 BIO_set_init(server_bio.get(), 1);
7224
7225 // Wrap the inner connections in another layer of SSL.
7226 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
7227 ASSERT_TRUE(client_outer);
7228 SSL_set_connect_state(client_outer.get());
7229 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
7230 client_bio.release(); // |SSL_set_bio| takes ownership.
7231
7232 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7233 ASSERT_TRUE(server_outer);
7234 SSL_set_accept_state(server_outer.get());
7235 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7236 server_bio.release(); // |SSL_set_bio| takes ownership.
7237
7238 // Configure |client_outer| to reject the server certificate.
7239 SSL_set_custom_verify(
7240 client_outer.get(), SSL_VERIFY_PEER,
7241 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7242 return ssl_verify_invalid;
7243 });
7244
7245 for (;;) {
7246 int client_ret = SSL_do_handshake(client_outer.get());
7247 int client_err = SSL_get_error(client_outer.get(), client_ret);
7248 if (client_err != SSL_ERROR_WANT_READ &&
7249 client_err != SSL_ERROR_WANT_WRITE) {
7250 // The client handshake should terminate on a certificate verification
7251 // error.
7252 EXPECT_EQ(SSL_ERROR_SSL, client_err);
7253 uint32_t err = ERR_peek_error();
7254 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7255 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
7256 break;
7257 }
7258
7259 // Run the server handshake and continue.
7260 int server_ret = SSL_do_handshake(server_outer.get());
7261 int server_err = SSL_get_error(server_outer.get(), server_ret);
7262 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7263 server_err == SSL_ERROR_WANT_READ ||
7264 server_err == SSL_ERROR_WANT_WRITE);
7265 }
7266}
7267
David Benjamin1b819472020-06-09 14:01:02 -04007268TEST_P(SSLVersionTest, SameKeyResume) {
7269 uint8_t key[48];
7270 RAND_bytes(key, sizeof(key));
7271
7272 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7273 ASSERT_TRUE(server_ctx2);
7274 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7275 ASSERT_TRUE(
7276 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7277 ASSERT_TRUE(
7278 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7279
7280 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7281 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7282 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7283
7284 // Establish a session for |server_ctx_|.
7285 bssl::UniquePtr<SSL_SESSION> session =
7286 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7287 ASSERT_TRUE(session);
7288 ClientConfig config;
7289 config.session = session.get();
7290
7291 // Resuming with |server_ctx_| again works.
7292 bssl::UniquePtr<SSL> client, server;
7293 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7294 server_ctx_.get(), config));
7295 EXPECT_TRUE(SSL_session_reused(client.get()));
7296 EXPECT_TRUE(SSL_session_reused(server.get()));
7297
7298 // Resuming with |server_ctx2| also works.
7299 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7300 server_ctx2.get(), config));
7301 EXPECT_TRUE(SSL_session_reused(client.get()));
7302 EXPECT_TRUE(SSL_session_reused(server.get()));
7303}
7304
7305TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7306 uint8_t key1[48], key2[48];
7307 RAND_bytes(key1, sizeof(key1));
7308 RAND_bytes(key2, sizeof(key2));
7309
7310 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7311 ASSERT_TRUE(server_ctx2);
7312 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7313 ASSERT_TRUE(
7314 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7315 ASSERT_TRUE(
7316 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7317
7318 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7319 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7320 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7321
7322 // Establish a session for |server_ctx_|.
7323 bssl::UniquePtr<SSL_SESSION> session =
7324 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7325 ASSERT_TRUE(session);
7326 ClientConfig config;
7327 config.session = session.get();
7328
7329 // Resuming with |server_ctx_| again works.
7330 bssl::UniquePtr<SSL> client, server;
7331 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7332 server_ctx_.get(), config));
7333 EXPECT_TRUE(SSL_session_reused(client.get()));
7334 EXPECT_TRUE(SSL_session_reused(server.get()));
7335
7336 // Resuming with |server_ctx2| does not work.
7337 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7338 server_ctx2.get(), config));
7339 EXPECT_FALSE(SSL_session_reused(client.get()));
7340 EXPECT_FALSE(SSL_session_reused(server.get()));
7341}
7342
7343TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7344 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7345 ASSERT_TRUE(server_ctx2);
7346 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7347
7348 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7349 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7350 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7351
7352 // Establish a session for |server_ctx_|.
7353 bssl::UniquePtr<SSL_SESSION> session =
7354 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7355 ASSERT_TRUE(session);
7356 ClientConfig config;
7357 config.session = session.get();
7358
7359 // Resuming with |server_ctx_| again works.
7360 bssl::UniquePtr<SSL> client, server;
7361 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7362 server_ctx_.get(), config));
7363 EXPECT_TRUE(SSL_session_reused(client.get()));
7364 EXPECT_TRUE(SSL_session_reused(server.get()));
7365
7366 // Resuming with |server_ctx2| does not work.
7367 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7368 server_ctx2.get(), config));
7369 EXPECT_FALSE(SSL_session_reused(client.get()));
7370 EXPECT_FALSE(SSL_session_reused(server.get()));
7371}
7372
Adam Langley47cefed2021-05-26 13:36:40 -07007373Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7374 const SSL_SESSION *session = SSL_get_session(ssl);
7375 unsigned len;
7376 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7377 return MakeConstSpan(data, len);
7378}
7379
7380TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7381 // This checks that the session IDs at client and server match after a ticket
7382 // resumption. It's unclear whether this should be true, but Envoy depends
7383 // on it in their tests so this will give an early signal if we break it.
7384 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7385 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7386
7387 bssl::UniquePtr<SSL_SESSION> session =
7388 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7389
7390 bssl::UniquePtr<SSL> client, server;
7391 ClientConfig config;
7392 config.session = session.get();
7393 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7394 server_ctx_.get(), config));
7395 EXPECT_TRUE(SSL_session_reused(client.get()));
7396 EXPECT_TRUE(SSL_session_reused(server.get()));
7397
7398 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7399}
7400
David Benjamin0e7dbd52019-05-15 16:01:18 -04007401TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04007402 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007403 ASSERT_TRUE(ctx);
7404
David Benjamin0e7dbd52019-05-15 16:01:18 -04007405 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7406 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7407 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7408 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7409
7410 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007411 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007412 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04007413 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007414
7415 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7416
7417 // Write "hello" until the buffer is full, so |client| has a pending write.
7418 size_t num_writes = 0;
7419 for (;;) {
7420 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7421 if (ret != int(sizeof(kInput))) {
7422 ASSERT_EQ(-1, ret);
7423 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7424 break;
7425 }
7426 num_writes++;
7427 }
7428
7429 // Encrypt a HelloRequest.
7430 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7431#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7432 // Fuzzer-mode records are unencrypted.
7433 uint8_t record[5 + sizeof(in)];
7434 record[0] = SSL3_RT_HANDSHAKE;
7435 record[1] = 3;
7436 record[2] = 3; // TLS 1.2
7437 record[3] = 0;
7438 record[4] = sizeof(record) - 5;
7439 memcpy(record + 5, in, sizeof(in));
7440#else
7441 // Extract key material from |server|.
7442 static const size_t kKeyLen = 32;
7443 static const size_t kNonceLen = 12;
7444 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
7445 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
7446 ASSERT_TRUE(
7447 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
7448 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7449 Span<uint8_t> nonce =
7450 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7451
7452 uint8_t ad[13];
7453 uint64_t seq = SSL_get_write_sequence(server.get());
7454 for (size_t i = 0; i < 8; i++) {
7455 // The nonce is XORed with the sequence number.
7456 nonce[11 - i] ^= uint8_t(seq);
7457 ad[7 - i] = uint8_t(seq);
7458 seq >>= 8;
7459 }
7460
7461 ad[8] = SSL3_RT_HANDSHAKE;
7462 ad[9] = 3;
7463 ad[10] = 3; // TLS 1.2
7464 ad[11] = 0;
7465 ad[12] = sizeof(in);
7466
7467 uint8_t record[5 + sizeof(in) + 16];
7468 record[0] = SSL3_RT_HANDSHAKE;
7469 record[1] = 3;
7470 record[2] = 3; // TLS 1.2
7471 record[3] = 0;
7472 record[4] = sizeof(record) - 5;
7473
7474 ScopedEVP_AEAD_CTX aead;
7475 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7476 key.data(), key.size(),
7477 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7478 size_t len;
7479 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7480 sizeof(record) - 5, nonce.data(), nonce.size(),
7481 in, sizeof(in), ad, sizeof(ad)));
7482 ASSERT_EQ(sizeof(record) - 5, len);
7483#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7484
7485 ASSERT_EQ(int(sizeof(record)),
7486 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
7487
7488 // |SSL_read| should pick up the HelloRequest.
7489 uint8_t byte;
7490 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7491 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7492
7493 // Drain the data from the |client|.
7494 uint8_t buf[sizeof(kInput)];
7495 for (size_t i = 0; i < num_writes; i++) {
7496 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7497 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7498 }
7499
7500 // |client| should be able to finish the pending write and continue to write,
7501 // despite the paused HelloRequest.
7502 ASSERT_EQ(int(sizeof(kInput)),
7503 SSL_write(client.get(), kInput, sizeof(kInput)));
7504 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7505 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7506
7507 ASSERT_EQ(int(sizeof(kInput)),
7508 SSL_write(client.get(), kInput, sizeof(kInput)));
7509 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7510 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7511
7512 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7513 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7514 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7515
7516 ASSERT_TRUE(SSL_renegotiate(client.get()));
7517 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7518 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7519
7520 // We never renegotiate as a server.
7521 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7522 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7523 uint32_t err = ERR_get_error();
7524 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7525 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7526}
7527
David Benjaminf9e0cda2020-03-23 18:29:09 -04007528
7529TEST(SSLTest, CopyWithoutEarlyData) {
7530 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007531 bssl::UniquePtr<SSL_CTX> server_ctx(
7532 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007533 ASSERT_TRUE(client_ctx);
7534 ASSERT_TRUE(server_ctx);
7535
David Benjaminf9e0cda2020-03-23 18:29:09 -04007536 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7537 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7538 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7539 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7540
7541 bssl::UniquePtr<SSL_SESSION> session =
7542 CreateClientSession(client_ctx.get(), server_ctx.get());
7543 ASSERT_TRUE(session);
7544
7545 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007546 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007547 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7548 server_ctx.get()));
7549 SSL_set_session(client.get(), session.get());
7550 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007551 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7552 EXPECT_TRUE(SSL_in_early_data(client.get()));
7553
7554 // |SSL_SESSION_copy_without_early_data| should disable early data but
7555 // still resume the session.
7556 bssl::UniquePtr<SSL_SESSION> session2(
7557 SSL_SESSION_copy_without_early_data(session.get()));
7558 ASSERT_TRUE(session2);
7559 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007560 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7561 server_ctx.get()));
7562 SSL_set_session(client.get(), session2.get());
7563 SSL_set_early_data_enabled(client.get(), 1);
7564 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007565 EXPECT_TRUE(SSL_session_reused(client.get()));
7566 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7567 SSL_get_early_data_reason(client.get()));
7568
7569 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7570 // when passed an early-data-incapable session.
7571 bssl::UniquePtr<SSL_SESSION> session3(
7572 SSL_SESSION_copy_without_early_data(session2.get()));
7573 EXPECT_EQ(session2.get(), session3.get());
7574}
7575
Adam Langley53a17f52020-05-26 14:44:07 -07007576TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7577 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007578 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007579 bssl::UniquePtr<SSL_CTX> server_ctx(
7580 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007581 ASSERT_TRUE(client_ctx);
7582 ASSERT_TRUE(server_ctx);
7583 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7584 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7585 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7586 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007587
7588 bssl::UniquePtr<SSL> client, server;
7589 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7590 server_ctx.get()));
7591 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7592
7593 // Process a TLS 1.3 NewSessionTicket.
7594 static const uint8_t kTicket[] = {
7595 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7596 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7597 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7598 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7599 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7600 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7601 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7602 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7603 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7604 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7605 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7606 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7607 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7608 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7609 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7610 0x00, 0x00,
7611 };
7612 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7613 client.get(), kTicket, sizeof(kTicket)));
7614 ASSERT_TRUE(session);
7615 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7616
7617 uint8_t *session_buf = nullptr;
7618 size_t session_length = 0;
7619 ASSERT_TRUE(
7620 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7621 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7622 ASSERT_TRUE(session_buf);
7623 ASSERT_GT(session_length, 0u);
7624
7625 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7626 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7627 sizeof(kTicket)));
7628
7629 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7630 // handshake completes.
7631 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7632 ASSERT_TRUE(client2);
7633 SSL_set_connect_state(client2.get());
7634 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7635 sizeof(kTicket)));
7636}
7637
David Benjamin3989c992020-10-09 14:12:06 -04007638TEST(SSLTest, BIO) {
7639 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007640 bssl::UniquePtr<SSL_CTX> server_ctx(
7641 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007642 ASSERT_TRUE(client_ctx);
7643 ASSERT_TRUE(server_ctx);
7644
David Benjamin3989c992020-10-09 14:12:06 -04007645 for (bool take_ownership : {true, false}) {
7646 // For simplicity, get the handshake out of the way first.
7647 bssl::UniquePtr<SSL> client, server;
7648 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7649 server_ctx.get()));
7650
7651 // Wrap |client| in an SSL BIO.
7652 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7653 ASSERT_TRUE(client_bio);
7654 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7655 if (take_ownership) {
7656 client.release();
7657 }
7658
7659 // Flushing the BIO should not crash.
7660 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7661
7662 // Exchange some data.
7663 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7664 uint8_t buf[5];
7665 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7666 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7667
7668 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7669 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7670 EXPECT_EQ(Bytes("world"), Bytes(buf));
7671
7672 // |BIO_should_read| should work.
7673 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7674 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7675
7676 // Writing data should eventually exceed the buffer size and fail, reporting
7677 // |BIO_should_write|.
7678 int ret;
7679 for (int i = 0; i < 1024; i++) {
7680 std::vector<uint8_t> buffer(1024);
7681 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7682 if (ret <= 0) {
7683 break;
7684 }
7685 }
7686 EXPECT_EQ(-1, ret);
7687 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7688 }
7689}
7690
David Benjamin12a3e7e2021-04-13 11:47:36 -04007691TEST(SSLTest, ALPNConfig) {
7692 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7693 ASSERT_TRUE(ctx);
7694 bssl::UniquePtr<X509> cert = GetTestCertificate();
7695 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7696 ASSERT_TRUE(cert);
7697 ASSERT_TRUE(key);
7698 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7699 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7700
7701 // Set up some machinery to check the configured ALPN against what is actually
7702 // sent over the wire. Note that the ALPN callback is only called when the
7703 // client offers ALPN.
7704 std::vector<uint8_t> observed_alpn;
7705 SSL_CTX_set_alpn_select_cb(
7706 ctx.get(),
7707 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7708 unsigned in_len, void *arg) -> int {
7709 std::vector<uint8_t> *observed_alpn_ptr =
7710 static_cast<std::vector<uint8_t> *>(arg);
7711 observed_alpn_ptr->assign(in, in + in_len);
7712 return SSL_TLSEXT_ERR_NOACK;
7713 },
7714 &observed_alpn);
7715 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7716 observed_alpn.clear();
7717 bssl::UniquePtr<SSL> client, server;
7718 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7719 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7720 };
7721
7722 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7723 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7724 0x03, 'b', 'a', 'r'};
7725 EXPECT_EQ(0,
7726 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7727 check_alpn_proto(kValidList);
7728
7729 // Invalid lists are rejected.
7730 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7731 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7732 sizeof(kInvalidList)));
7733
7734 // Empty lists are valid and are interpreted as disabling ALPN.
7735 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7736 check_alpn_proto({});
7737}
7738
David Benjamin2f3958a2021-04-16 11:55:23 -04007739// Test that the key usage checker can correctly handle issuerUID and
7740// subjectUID. See https://crbug.com/1199744.
7741TEST(SSLTest, KeyUsageWithUIDs) {
7742 static const char kGoodKeyUsage[] = R"(
7743-----BEGIN CERTIFICATE-----
7744MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7745AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7746aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7747CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7748ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
77494r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7750Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7751ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7752A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
775334EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
77544Z7qDhjIhiF4dM0uEDYRVA==
7755-----END CERTIFICATE-----
7756)";
7757 static const char kBadKeyUsage[] = R"(
7758-----BEGIN CERTIFICATE-----
7759MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7760AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7761aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7762CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7763ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
77644r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7765Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7766ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7767A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7768taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7769RHrQbWsFUakETXL9QMlegh5t
7770-----END CERTIFICATE-----
7771)";
7772
7773 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7774 ASSERT_TRUE(good);
7775 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7776 ASSERT_TRUE(bad);
7777
7778 // We check key usage when configuring EC certificates to distinguish ECDSA
7779 // and ECDH.
7780 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7781 ASSERT_TRUE(ctx);
7782 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7783 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7784}
7785
David Benjamin9b2cdb72021-04-01 23:21:53 -04007786// Test that |SSL_can_release_private_key| reports true as early as expected.
7787// The internal asserts in the library check we do not report true too early.
7788TEST(SSLTest, CanReleasePrivateKey) {
7789 bssl::UniquePtr<SSL_CTX> client_ctx =
7790 CreateContextWithTestCertificate(TLS_method());
7791 ASSERT_TRUE(client_ctx);
7792 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7793
7794 // Note this assumes the transport buffer is large enough to fit the client
7795 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7796 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7797 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7798 // Write the ClientHello.
7799 ASSERT_EQ(-1, SSL_do_handshake(client));
7800 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7801
7802 // Consume the ClientHello and write the server flight.
7803 ASSERT_EQ(-1, SSL_do_handshake(server));
7804 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7805
7806 EXPECT_TRUE(SSL_can_release_private_key(server));
7807 };
7808
7809 {
7810 SCOPED_TRACE("TLS 1.2 ECDHE");
7811 bssl::UniquePtr<SSL_CTX> server_ctx(
7812 CreateContextWithTestCertificate(TLS_method()));
7813 ASSERT_TRUE(server_ctx);
7814 ASSERT_TRUE(
7815 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7816 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7817 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7818 // Configure the server to request client certificates, so we can also test
7819 // the client half.
7820 SSL_CTX_set_custom_verify(
7821 server_ctx.get(), SSL_VERIFY_PEER,
7822 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7823 bssl::UniquePtr<SSL> client, server;
7824 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7825 server_ctx.get()));
7826 check_first_server_round_trip(client.get(), server.get());
7827
7828 // Consume the server flight and write the client response. The client still
7829 // has a Finished message to consume but can also release its key early.
7830 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7831 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7832 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7833
7834 // However, a client that has not disabled renegotiation can never release
7835 // the key.
7836 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7837 server_ctx.get()));
7838 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7839 check_first_server_round_trip(client.get(), server.get());
7840 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7841 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7842 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7843 }
7844
7845 {
7846 SCOPED_TRACE("TLS 1.2 resumption");
7847 bssl::UniquePtr<SSL_CTX> server_ctx(
7848 CreateContextWithTestCertificate(TLS_method()));
7849 ASSERT_TRUE(server_ctx);
7850 ASSERT_TRUE(
7851 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7852 bssl::UniquePtr<SSL_SESSION> session =
7853 CreateClientSession(client_ctx.get(), server_ctx.get());
7854 ASSERT_TRUE(session);
7855 bssl::UniquePtr<SSL> client, server;
7856 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7857 server_ctx.get()));
7858 SSL_set_session(client.get(), session.get());
7859 check_first_server_round_trip(client.get(), server.get());
7860 }
7861
7862 {
7863 SCOPED_TRACE("TLS 1.3 1-RTT");
7864 bssl::UniquePtr<SSL_CTX> server_ctx(
7865 CreateContextWithTestCertificate(TLS_method()));
7866 ASSERT_TRUE(server_ctx);
7867 ASSERT_TRUE(
7868 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7869 bssl::UniquePtr<SSL> client, server;
7870 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7871 server_ctx.get()));
7872 check_first_server_round_trip(client.get(), server.get());
7873 }
7874
7875 {
7876 SCOPED_TRACE("TLS 1.3 resumption");
7877 bssl::UniquePtr<SSL_CTX> server_ctx(
7878 CreateContextWithTestCertificate(TLS_method()));
7879 ASSERT_TRUE(server_ctx);
7880 ASSERT_TRUE(
7881 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7882 bssl::UniquePtr<SSL_SESSION> session =
7883 CreateClientSession(client_ctx.get(), server_ctx.get());
7884 ASSERT_TRUE(session);
7885 bssl::UniquePtr<SSL> client, server;
7886 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7887 server_ctx.get()));
7888 SSL_set_session(client.get(), session.get());
7889 check_first_server_round_trip(client.get(), server.get());
7890 }
7891}
7892
David Benjamine9c5d722021-06-09 17:43:16 -04007893// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7894// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7895// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7896// will be set to the ClientHelloInner's extensions, rather than
7897// ClientHelloOuter.
7898static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7899 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7900 struct AppData {
7901 std::vector<uint16_t> *out;
7902 bool decrypt_ech;
7903 bool callback_done = false;
7904 };
7905 AppData app_data;
7906 app_data.out = out;
7907 app_data.decrypt_ech = decrypt_ech;
7908
7909 bssl::UniquePtr<SSL_CTX> server_ctx =
7910 CreateContextWithTestCertificate(TLS_method());
7911 if (!server_ctx || //
7912 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7913 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7914 return false;
7915 }
7916
7917 // Configure the server to record the ClientHello extension order. We use a
7918 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7919 SSL_CTX_set_select_certificate_cb(
7920 server_ctx.get(),
7921 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7922 AppData *app_data_ptr = static_cast<AppData *>(
7923 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7924 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7925 SSL_ech_accepted(client_hello->ssl));
7926
7927 app_data_ptr->out->clear();
7928 CBS extensions;
7929 CBS_init(&extensions, client_hello->extensions,
7930 client_hello->extensions_len);
7931 while (CBS_len(&extensions)) {
7932 uint16_t type;
7933 CBS body;
7934 if (!CBS_get_u16(&extensions, &type) ||
7935 !CBS_get_u16_length_prefixed(&extensions, &body)) {
7936 return ssl_select_cert_error;
7937 }
7938 app_data_ptr->out->push_back(type);
7939 }
7940
7941 // Don't bother completing the handshake.
7942 app_data_ptr->callback_done = true;
7943 return ssl_select_cert_error;
7944 });
7945
7946 bssl::UniquePtr<SSL> client, server;
7947 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
7948 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
7949 return false;
7950 }
7951
7952 // Run the handshake far enough to process the ClientHello.
7953 SSL_do_handshake(client.get());
7954 SSL_do_handshake(server.get());
7955 return app_data.callback_done;
7956}
7957
7958// Test that, when extension permutation is enabled, the ClientHello extension
7959// order changes, both with and without ECH, and in both ClientHelloInner and
7960// ClientHelloOuter.
7961TEST(SSLTest, PermuteExtensions) {
7962 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
7963 ASSERT_TRUE(keys);
7964 for (bool offer_ech : {false, true}) {
7965 SCOPED_TRACE(offer_ech);
7966 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
7967 for (bool decrypt_ech : {false, true}) {
7968 SCOPED_TRACE(decrypt_ech);
7969 if (!offer_ech && decrypt_ech) {
7970 continue;
7971 }
7972
7973 // When extension permutation is disabled, the order should be consistent.
7974 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7975 ASSERT_TRUE(ctx);
7976 std::vector<uint16_t> order1, order2;
7977 ASSERT_TRUE(
7978 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7979 ASSERT_TRUE(
7980 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7981 EXPECT_EQ(order1, order2);
7982
7983 ctx.reset(SSL_CTX_new(TLS_method()));
7984 ASSERT_TRUE(ctx);
7985 SSL_CTX_set_permute_extensions(ctx.get(), 1);
7986
7987 // When extension permutation is enabled, each ClientHello should have a
7988 // different order.
7989 //
7990 // This test is inherently flaky, so we run it multiple times. We send at
7991 // least five extensions by default from TLS 1.3: supported_versions,
7992 // key_share, supported_groups, psk_key_exchange_modes, and
7993 // signature_algorithms. That means the probability of a false negative is
7994 // at most 1/120. Repeating the test 14 times lowers false negative rate
7995 // to under 2^-96.
7996 ASSERT_TRUE(
7997 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7998 EXPECT_GE(order1.size(), 5u);
7999 static const int kNumIterations = 14;
8000 bool passed = false;
8001 for (int i = 0; i < kNumIterations; i++) {
8002 ASSERT_TRUE(
8003 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8004 if (order1 != order2) {
8005 passed = true;
8006 break;
8007 }
8008 }
8009 EXPECT_TRUE(passed) << "Extensions were not permuted";
8010 }
8011 }
8012}
8013
Adam Langley7e7e6b62021-12-06 13:04:07 -08008014TEST(SSLTest, HostMatching) {
David Benjaminc3c540b2021-12-08 15:12:51 -05008015 static const char kCertPEM[] = R"(
8016-----BEGIN CERTIFICATE-----
8017MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw
8018DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2
8019MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD
8020VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO
8021Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW
8022ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr
8023BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3
8024Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP
8025YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD
8026AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu
80275DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY=
8028-----END CERTIFICATE-----
8029)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008030 bssl::UniquePtr<X509> cert(CertFromPEM(kCertPEM));
8031 ASSERT_TRUE(cert);
David Benjaminc3c540b2021-12-08 15:12:51 -05008032 static const char kCertNoSANsPEM[] = R"(
8033-----BEGIN CERTIFICATE-----
8034MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw
8035EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy
8036MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV
8037MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
8038u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw
8039L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG
8040CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG
8041SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW
8042pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4=
8043-----END CERTIFICATE-----
8044)";
8045 bssl::UniquePtr<X509> cert_no_sans(CertFromPEM(kCertNoSANsPEM));
8046 ASSERT_TRUE(cert_no_sans);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008047
David Benjaminc3c540b2021-12-08 15:12:51 -05008048 static const char kKeyPEM[] = R"(
8049-----BEGIN PRIVATE KEY-----
8050MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ
8051MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+
8052RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
8053-----END PRIVATE KEY-----
8054)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008055 bssl::UniquePtr<EVP_PKEY> key(KeyFromPEM(kKeyPEM));
8056 ASSERT_TRUE(key);
8057
Adam Langley7e7e6b62021-12-06 13:04:07 -08008058 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8059 ASSERT_TRUE(client_ctx);
8060 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8061 cert.get()));
David Benjaminc3c540b2021-12-08 15:12:51 -05008062 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8063 cert_no_sans.get()));
Adam Langley7e7e6b62021-12-06 13:04:07 -08008064 SSL_CTX_set_verify(client_ctx.get(),
8065 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
8066 nullptr);
8067
8068 struct TestCase {
David Benjaminc3c540b2021-12-08 15:12:51 -05008069 X509 *cert;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008070 std::string hostname;
8071 unsigned flags;
8072 bool should_match;
8073 };
8074 std::vector<TestCase> kTests = {
8075 // These two names are present as SANs in the certificate.
David Benjaminc3c540b2021-12-08 15:12:51 -05008076 {cert.get(), "example1.com", 0, true},
8077 {cert.get(), "example2.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008078 // This is the CN of the certificate, but that shouldn't matter if a SAN
8079 // extension is present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008080 {cert.get(), "example3.com", 0, false},
8081 // If the SAN is not present, we, for now, look for DNS names in the CN.
8082 {cert_no_sans.get(), "example3.com", 0, true},
8083 // ... but this can be turned off.
8084 {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT,
8085 false},
8086 // a*.example4.com is a SAN, but is invalid.
8087 {cert.get(), "abc.example4.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008088 // *.example5.com is a SAN in the certificate, which is a normal and valid
8089 // wildcard.
David Benjaminc3c540b2021-12-08 15:12:51 -05008090 {cert.get(), "abc.example5.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008091 // This name is not present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008092 {cert.get(), "notexample1.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008093 // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a
8094 // hostname that happens to be its textual representation.
David Benjaminc3c540b2021-12-08 15:12:51 -05008095 {cert.get(), "1.2.3.4", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008096 };
8097
Adam Langley7e7e6b62021-12-06 13:04:07 -08008098 for (const TestCase &test : kTests) {
8099 SCOPED_TRACE(test.hostname);
David Benjaminc3c540b2021-12-08 15:12:51 -05008100
8101 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8102 ASSERT_TRUE(server_ctx);
8103 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert));
8104 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8105
8106 ClientConfig config;
8107 bssl::UniquePtr<SSL> client, server;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008108 config.verify_hostname = test.hostname;
8109 config.hostflags = test.flags;
8110 EXPECT_EQ(test.should_match,
8111 ConnectClientAndServer(&client, &server, client_ctx.get(),
8112 server_ctx.get(), config));
8113 }
8114}
8115
David Benjamin3f180b82022-05-09 17:45:18 -04008116TEST(SSLTest, NumTickets) {
8117 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8118 ASSERT_TRUE(server_ctx);
8119 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8120 ASSERT_TRUE(client_ctx);
8121 bssl::UniquePtr<X509> cert = GetTestCertificate();
8122 ASSERT_TRUE(cert);
8123 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8124 ASSERT_TRUE(key);
8125 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
8126 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8127 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8128
8129 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8130 static size_t ticket_count;
8131 SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int {
8132 ticket_count++;
8133 return 0;
8134 });
8135
8136 auto count_tickets = [&]() -> size_t {
8137 ticket_count = 0;
8138 bssl::UniquePtr<SSL> client, server;
8139 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
8140 server_ctx.get()) ||
8141 !FlushNewSessionTickets(client.get(), server.get())) {
8142 ADD_FAILURE() << "Could not run handshake";
8143 return 0;
8144 }
8145 return ticket_count;
8146 };
8147
8148 // By default, we should send two tickets.
8149 EXPECT_EQ(count_tickets(), 2u);
8150
8151 for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) {
8152 SCOPED_TRACE(num_tickets);
8153 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets));
8154 EXPECT_EQ(count_tickets(), num_tickets);
8155 }
8156
8157 // Configuring too many tickets causes us to stop at some point.
8158 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000));
8159 EXPECT_EQ(count_tickets(), 16u);
8160}
8161
David Benjamin955ef792022-06-13 13:16:43 -04008162TEST(SSLTest, CertSubjectsToStack) {
8163 const std::string kCert1 = R"(
8164-----BEGIN CERTIFICATE-----
8165MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
8166QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
8167dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
8168BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
8169dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
8170v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
8171HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
8172HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
8173BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
8174BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
8175-----END CERTIFICATE-----
8176)";
8177 const std::vector<uint8_t> kName1 = {
8178 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
8179 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
8180 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
8181 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
8182 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
8183 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
8184 const std::string kCert2 = R"(
8185-----BEGIN CERTIFICATE-----
8186MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE
8187ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg
8188Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y
8189aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3
8190DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c
8191oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j
81925x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh
8193TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
8194CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0
81954nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB
8196gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y
8197rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU
8198xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==
8199-----END CERTIFICATE-----
8200)";
8201 const std::vector<uint8_t> kName2 = {
8202 0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a,
8203 0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c,
8204 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30,
8205 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61,
8206 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
8207
8208 const struct {
8209 std::vector<std::vector<uint8_t>> existing;
8210 std::string pem;
8211 std::vector<std::vector<uint8_t>> expected;
8212 } kTests[] = {
8213 // Do nothing.
8214 {{}, "", {}},
8215 // Append to an empty list, skipping duplicates.
8216 {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}},
8217 // One of the names was already present.
8218 {{kName1}, kCert1 + kCert2, {kName1, kName2}},
8219 // Both names were already present.
8220 {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}},
8221 // Preserve existing duplicates.
8222 {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}},
8223 };
8224 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
8225 SCOPED_TRACE(i);
8226 const auto &t = kTests[i];
8227
8228 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
8229 ASSERT_TRUE(stack);
8230 for (const auto& name : t.existing) {
8231 const uint8_t *inp = name.data();
8232 bssl::UniquePtr<X509_NAME> name_obj(
8233 d2i_X509_NAME(nullptr, &inp, name.size()));
8234 ASSERT_TRUE(name_obj);
8235 EXPECT_EQ(inp, name.data() + name.size());
8236 ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj)));
8237 }
8238
8239 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(t.pem.data(), t.pem.size()));
8240 ASSERT_TRUE(bio);
8241 ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get()));
8242
8243 // The function should have left |stack|'s comparison function alone.
8244 EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr));
8245
8246 std::vector<std::vector<uint8_t>> expected = t.expected, result;
8247 for (X509_NAME *name : stack.get()) {
8248 uint8_t *der = nullptr;
8249 int der_len = i2d_X509_NAME(name, &der);
8250 ASSERT_GE(der_len, 0);
8251 result.push_back(std::vector<uint8_t>(der, der + der_len));
8252 OPENSSL_free(der);
8253 }
8254
8255 // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a
8256 // well-defined order.
8257 std::sort(expected.begin(), expected.end());
8258 std::sort(result.begin(), result.end());
8259 EXPECT_EQ(result, expected);
8260 }
8261}
8262
Martin Kreichgauer72912d22017-08-04 12:06:43 -07008263} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07008264BSSL_NAMESPACE_END