blob: 3515f602f192369bfc25b1df0bb8a71d3320afb7 [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 Benjamin64bf8c52022-07-22 15:49:45 -07003907static bool ExpectSingleError(int lib, int reason) {
3908 const char *expected = ERR_reason_error_string(ERR_PACK(lib, reason));
David Benjamin48063c22017-01-01 23:56:36 -05003909 int err = ERR_get_error();
David Benjamin64bf8c52022-07-22 15:49:45 -07003910 if (ERR_GET_LIB(err) != lib || ERR_GET_REASON(err) != reason) {
David Benjamin48063c22017-01-01 23:56:36 -05003911 char buf[ERR_ERROR_STRING_BUF_LEN];
3912 ERR_error_string_n(err, buf, sizeof(buf));
David Benjamin64bf8c52022-07-22 15:49:45 -07003913 fprintf(stderr, "Wanted %s, got: %s.\n", expected, buf);
David Benjamin48063c22017-01-01 23:56:36 -05003914 return false;
3915 }
3916
3917 if (ERR_peek_error() != 0) {
David Benjamin64bf8c52022-07-22 15:49:45 -07003918 fprintf(stderr, "Unexpected error following %s.\n", expected);
David Benjamin48063c22017-01-01 23:56:36 -05003919 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(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003935
3936 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003937 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003938 }
3939
3940 // Write without reading until the buffer is full and we have an unfinished
3941 // write. Keep a count so we may reread it again later. "hello!" will be
3942 // written in two chunks, "hello" and "!".
3943 char data[] = "hello!";
3944 static const int kChunkLen = 5; // The length of "hello".
3945 unsigned count = 0;
3946 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003947 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003948 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003949 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3950 break;
David Benjamin48063c22017-01-01 23:56:36 -05003951 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003952 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003953 count++;
3954 }
3955
3956 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003957 ASSERT_EQ(
3958 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3959 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003960
3961 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003962 ASSERT_EQ(SSL_get_error(client_.get(),
3963 SSL_write(client_.get(), data, kChunkLen - 1)),
3964 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07003965 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05003966
3967 // Retrying with a different buffer pointer is not legal.
3968 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003969 ASSERT_EQ(SSL_get_error(client_.get(),
3970 SSL_write(client_.get(), data2, kChunkLen)),
3971 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07003972 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05003973
3974 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003975 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3976 ASSERT_EQ(SSL_get_error(client_.get(),
3977 SSL_write(client_.get(), data2, kChunkLen)),
3978 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003979
3980 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003981 ASSERT_EQ(SSL_get_error(client_.get(),
3982 SSL_write(client_.get(), data2, kChunkLen - 1)),
3983 SSL_ERROR_SSL);
David Benjamin64bf8c52022-07-22 15:49:45 -07003984 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
David Benjamin48063c22017-01-01 23:56:36 -05003985
3986 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003987 ASSERT_EQ(SSL_get_error(client_.get(),
3988 SSL_write(client_.get(), data, kChunkLen + 1)),
3989 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003990
3991 // Drain the buffer.
3992 char buf[20];
3993 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003994 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3995 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003996 }
3997
3998 // Now that there is space, a retry with a larger buffer should flush the
3999 // pending record, skip over that many bytes of input (on assumption they
4000 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
4001 // is set, this will complete in two steps.
David Benjamin64bf8c52022-07-22 15:49:45 -07004002 char data_longer[] = "_____!!!!!";
David Benjamin48063c22017-01-01 23:56:36 -05004003 if (enable_partial_write) {
David Benjamin64bf8c52022-07-22 15:49:45 -07004004 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4005 kChunkLen);
4006 ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4007 kChunkLen);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004008 } else {
David Benjamin64bf8c52022-07-22 15:49:45 -07004009 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4010 2 * kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05004011 }
4012
4013 // Check the last write was correct. The data will be spread over two
4014 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004015 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4016 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin64bf8c52022-07-22 15:49:45 -07004017 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4018 ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
4019
4020 // Fill the transport buffer again. This time only leave room for one
4021 // record.
4022 count = 0;
4023 for (;;) {
4024 int ret = SSL_write(client_.get(), data, kChunkLen);
4025 if (ret <= 0) {
4026 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
4027 break;
4028 }
4029 ASSERT_EQ(ret, 5);
4030 count++;
4031 }
4032 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4033 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4034 count--;
4035
4036 // Retry the last write, with a longer input. The first half is the most
4037 // recently failed write, from filling the buffer. |SSL_write| should write
4038 // that to the transport, and then attempt to write the second half.
4039 int ret = SSL_write(client_.get(), data_longer, 2 * kChunkLen);
4040 if (enable_partial_write) {
4041 // If partial writes are allowed, the write will succeed partially.
4042 ASSERT_EQ(ret, kChunkLen);
4043
4044 // Check the first half and make room for another record.
4045 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4046 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4047 count--;
4048
4049 // Finish writing the input.
4050 ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4051 kChunkLen);
4052 } else {
4053 // Otherwise, although the first half made it to the transport, the second
4054 // half is blocked.
4055 ASSERT_EQ(ret, -1);
4056 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_WRITE);
4057
4058 // Check the first half and make room for another record.
4059 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4060 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4061 count--;
4062
4063 // Retrying with fewer bytes than previously attempted is an error. If the
4064 // input length is less than the number of bytes successfully written, the
4065 // check happens at a different point, with a different error.
4066 //
4067 // TODO(davidben): Should these cases use the same error?
4068 ASSERT_EQ(
4069 SSL_get_error(client_.get(),
4070 SSL_write(client_.get(), data_longer, kChunkLen - 1)),
4071 SSL_ERROR_SSL);
4072 ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_LENGTH));
4073
4074 // Complete the write with the correct retry.
4075 ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4076 2 * kChunkLen);
4077 }
4078
4079 // Drain the input and ensure everything was written correctly.
4080 for (unsigned i = 0; i < count; i++) {
4081 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4082 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4083 }
4084
4085 // The final write is spread over two records.
4086 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4087 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4088 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4089 ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05004090 }
David Benjamin48063c22017-01-01 23:56:36 -05004091}
4092
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004093TEST_P(SSLVersionTest, RecordCallback) {
4094 for (bool test_server : {true, false}) {
4095 SCOPED_TRACE(test_server);
4096 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04004097
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004098 bool read_seen = false;
4099 bool write_seen = false;
4100 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
4101 size_t len, SSL *ssl) {
4102 if (cb_type != SSL3_RT_HEADER) {
4103 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004104 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004105
4106 // The callback does not report a version for records.
4107 EXPECT_EQ(0, cb_version);
4108
4109 if (is_write) {
4110 write_seen = true;
4111 } else {
4112 read_seen = true;
4113 }
4114
4115 // Sanity-check that the record header is plausible.
4116 CBS cbs;
4117 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
4118 uint8_t type;
4119 uint16_t record_version, length;
4120 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
4121 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05004122 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004123 if (is_dtls()) {
4124 uint16_t epoch;
4125 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
4126 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
4127 ASSERT_TRUE(CBS_skip(&cbs, 6));
4128 }
4129 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
4130 EXPECT_EQ(0u, CBS_len(&cbs));
4131 };
4132 using CallbackType = decltype(cb);
4133 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
4134 SSL_CTX_set_msg_callback(
4135 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
4136 size_t len, SSL *ssl, void *arg) {
4137 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
4138 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
4139 });
4140 SSL_CTX_set_msg_callback_arg(ctx, &cb);
4141
4142 ASSERT_TRUE(Connect());
4143
4144 EXPECT_TRUE(read_seen);
4145 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09004146 }
David Benjamin9ef31f02016-10-31 18:01:13 -04004147}
4148
David Benjamina8614602017-09-06 15:40:19 -04004149TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04004150 ClientConfig config;
4151 config.servername = "host1";
4152
4153 SSL_CTX_set_tlsext_servername_callback(
4154 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
4155 // During the handshake, |SSL_get_servername| must match |config|.
4156 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
4157 EXPECT_STREQ(config_p->servername.c_str(),
4158 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
4159 return SSL_TLSEXT_ERR_OK;
4160 });
4161 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
4162
4163 ASSERT_TRUE(Connect(config));
4164 // After the handshake, it must also be available.
4165 EXPECT_STREQ(config.servername.c_str(),
4166 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4167
4168 // Establish a session under host1.
4169 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4170 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4171 bssl::UniquePtr<SSL_SESSION> session =
4172 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
4173
4174 // If the client resumes a session with a different name, |SSL_get_servername|
4175 // must return the new name.
4176 ASSERT_TRUE(session);
4177 config.session = session.get();
4178 config.servername = "host2";
4179 ASSERT_TRUE(Connect(config));
4180 EXPECT_STREQ(config.servername.c_str(),
4181 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4182}
4183
David Benjamin3d8f0802017-09-06 16:12:52 -04004184// Test that session cache mode bits are honored in the client session callback.
4185TEST_P(SSLVersionTest, ClientSessionCacheMode) {
4186 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
4187 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4188
4189 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
4190 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4191
4192 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
4193 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4194}
4195
Steven Valdez777a2392019-02-21 11:30:47 -05004196// Test that all versions survive tiny write buffers. In particular, TLS 1.3
4197// NewSessionTickets are written post-handshake. Servers that block
4198// |SSL_do_handshake| on writing them will deadlock if clients are not draining
4199// the buffer. Test that we do not do this.
4200TEST_P(SSLVersionTest, SmallBuffer) {
4201 // DTLS is a datagram protocol and requires packet-sized buffers.
4202 if (is_dtls()) {
4203 return;
4204 }
4205
4206 // Test both flushing NewSessionTickets with a zero-sized write and
4207 // non-zero-sized write.
4208 for (bool use_zero_write : {false, true}) {
4209 SCOPED_TRACE(use_zero_write);
4210
4211 g_last_session = nullptr;
4212 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4213 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
4214
4215 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
4216 server(SSL_new(server_ctx_.get()));
4217 ASSERT_TRUE(client);
4218 ASSERT_TRUE(server);
4219 SSL_set_connect_state(client.get());
4220 SSL_set_accept_state(server.get());
4221
4222 // Use a tiny buffer.
4223 BIO *bio1, *bio2;
4224 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
4225
4226 // SSL_set_bio takes ownership.
4227 SSL_set_bio(client.get(), bio1, bio1);
4228 SSL_set_bio(server.get(), bio2, bio2);
4229
4230 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4231 if (version() >= TLS1_3_VERSION) {
4232 // The post-handshake ticket should not have been processed yet.
4233 EXPECT_FALSE(g_last_session);
4234 }
4235
4236 if (use_zero_write) {
4237 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
4238 EXPECT_TRUE(g_last_session);
4239 }
4240
4241 // Send some data from server to client. If |use_zero_write| is false, this
4242 // will also flush the NewSessionTickets.
4243 static const char kMessage[] = "hello world";
4244 char buf[sizeof(kMessage)];
4245 for (;;) {
4246 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
4247 int server_err = SSL_get_error(server.get(), server_ret);
4248 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
4249 int client_err = SSL_get_error(client.get(), client_ret);
4250
4251 // The server will write a single record, so every iteration should see
4252 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
4253 // iteration, where both will complete.
4254 if (server_ret > 0) {
4255 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
4256 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
4257 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
4258 break;
4259 }
4260
4261 ASSERT_EQ(server_ret, -1);
4262 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
4263 ASSERT_EQ(client_ret, -1);
4264 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4265 }
4266
4267 // The NewSessionTickets should have been flushed and processed.
4268 EXPECT_TRUE(g_last_session);
4269 }
4270}
4271
Adam Langleye1e78132017-01-31 15:24:31 -08004272TEST(SSLTest, AddChainCertHack) {
4273 // Ensure that we don't accidently break the hack that we have in place to
4274 // keep curl and serf happy when they use an |X509| even after transfering
4275 // ownership.
4276
4277 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4278 ASSERT_TRUE(ctx);
4279 X509 *cert = GetTestCertificate().release();
4280 ASSERT_TRUE(cert);
4281 SSL_CTX_add0_chain_cert(ctx.get(), cert);
4282
4283 // This should not trigger a use-after-free.
4284 X509_cmp(cert, cert);
4285}
4286
David Benjaminb2ff2622017-02-03 17:06:18 -05004287TEST(SSLTest, GetCertificate) {
4288 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4289 ASSERT_TRUE(ctx);
4290 bssl::UniquePtr<X509> cert = GetTestCertificate();
4291 ASSERT_TRUE(cert);
4292 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4293 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4294 ASSERT_TRUE(ssl);
4295
4296 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4297 ASSERT_TRUE(cert2);
4298 X509 *cert3 = SSL_get_certificate(ssl.get());
4299 ASSERT_TRUE(cert3);
4300
4301 // The old and new certificates must be identical.
4302 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4303 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
4304
4305 uint8_t *der = nullptr;
4306 long der_len = i2d_X509(cert.get(), &der);
4307 ASSERT_LT(0, der_len);
4308 bssl::UniquePtr<uint8_t> free_der(der);
4309
4310 uint8_t *der2 = nullptr;
4311 long der2_len = i2d_X509(cert2, &der2);
4312 ASSERT_LT(0, der2_len);
4313 bssl::UniquePtr<uint8_t> free_der2(der2);
4314
4315 uint8_t *der3 = nullptr;
4316 long der3_len = i2d_X509(cert3, &der3);
4317 ASSERT_LT(0, der3_len);
4318 bssl::UniquePtr<uint8_t> free_der3(der3);
4319
4320 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05004321 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4322 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05004323}
4324
Adam Langleyd04ca952017-02-28 11:26:51 -08004325TEST(SSLTest, SetChainAndKeyMismatch) {
4326 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4327 ASSERT_TRUE(ctx);
4328
4329 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4330 ASSERT_TRUE(key);
4331 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4332 ASSERT_TRUE(leaf);
4333 std::vector<CRYPTO_BUFFER*> chain = {
4334 leaf.get(),
4335 };
4336
4337 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
4338 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
4339 key.get(), nullptr));
4340 ERR_clear_error();
4341}
4342
4343TEST(SSLTest, SetChainAndKey) {
4344 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4345 ASSERT_TRUE(client_ctx);
4346 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4347 ASSERT_TRUE(server_ctx);
4348
Adam Langley964256d2020-03-19 11:57:12 -07004349 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4350
Adam Langleyd04ca952017-02-28 11:26:51 -08004351 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4352 ASSERT_TRUE(key);
4353 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4354 ASSERT_TRUE(leaf);
4355 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4356 GetChainTestIntermediateBuffer();
4357 ASSERT_TRUE(intermediate);
4358 std::vector<CRYPTO_BUFFER*> chain = {
4359 leaf.get(), intermediate.get(),
4360 };
4361 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4362 chain.size(), key.get(), nullptr));
4363
Adam Langley964256d2020-03-19 11:57:12 -07004364 ASSERT_EQ(chain.size(),
4365 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4366
David Benjamin3a1dd462017-07-11 16:13:10 -04004367 SSL_CTX_set_custom_verify(
4368 client_ctx.get(), SSL_VERIFY_PEER,
4369 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4370 return ssl_verify_ok;
4371 });
Adam Langleyd04ca952017-02-28 11:26:51 -08004372
4373 bssl::UniquePtr<SSL> client, server;
4374 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004375 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08004376}
4377
Matthew Braithwaite5301c102018-01-23 12:08:55 -08004378TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4379 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4380 ASSERT_TRUE(client_ctx);
4381 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4382 ASSERT_TRUE(server_ctx);
4383
4384 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4385 ASSERT_TRUE(key);
4386 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4387 ASSERT_TRUE(leaf);
4388 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4389 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4390 chain.size(), key.get(), nullptr));
4391
4392 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4393 // configuration, certificate verification should fail.
4394 bssl::UniquePtr<SSL> client, server;
4395 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4396 server_ctx.get()));
4397
4398 // Whereas with a verifier, the connection should succeed.
4399 SSL_CTX_set_custom_verify(
4400 client_ctx.get(), SSL_VERIFY_PEER,
4401 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4402 return ssl_verify_ok;
4403 });
4404 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4405 server_ctx.get()));
4406}
4407
4408TEST(SSLTest, CustomVerify) {
4409 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4410 ASSERT_TRUE(client_ctx);
4411 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4412 ASSERT_TRUE(server_ctx);
4413
4414 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4415 ASSERT_TRUE(key);
4416 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4417 ASSERT_TRUE(leaf);
4418 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4419 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4420 chain.size(), key.get(), nullptr));
4421
4422 SSL_CTX_set_custom_verify(
4423 client_ctx.get(), SSL_VERIFY_PEER,
4424 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4425 return ssl_verify_ok;
4426 });
4427
4428 bssl::UniquePtr<SSL> client, server;
4429 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4430 server_ctx.get()));
4431
4432 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4433 // connection.
4434 SSL_CTX_set_custom_verify(
4435 client_ctx.get(), SSL_VERIFY_PEER,
4436 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4437 return ssl_verify_invalid;
4438 });
4439
4440 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4441 server_ctx.get()));
4442
4443 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4444 // connection.
4445 SSL_CTX_set_custom_verify(
4446 client_ctx.get(), SSL_VERIFY_NONE,
4447 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4448 return ssl_verify_invalid;
4449 });
4450
4451 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4452 server_ctx.get()));
4453}
4454
David Benjamin71dfad42017-07-16 17:27:39 -04004455TEST(SSLTest, ClientCABuffers) {
4456 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4457 ASSERT_TRUE(client_ctx);
4458 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4459 ASSERT_TRUE(server_ctx);
4460
4461 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4462 ASSERT_TRUE(key);
4463 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4464 ASSERT_TRUE(leaf);
4465 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4466 GetChainTestIntermediateBuffer();
4467 ASSERT_TRUE(intermediate);
4468 std::vector<CRYPTO_BUFFER *> chain = {
4469 leaf.get(),
4470 intermediate.get(),
4471 };
4472 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
4473 chain.size(), key.get(), nullptr));
4474
4475 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4476 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4477 ASSERT_TRUE(ca_name);
4478 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4479 sk_CRYPTO_BUFFER_new_null());
4480 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04004481 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04004482 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
4483
4484 // Configure client and server to accept all certificates.
4485 SSL_CTX_set_custom_verify(
4486 client_ctx.get(), SSL_VERIFY_PEER,
4487 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4488 return ssl_verify_ok;
4489 });
4490 SSL_CTX_set_custom_verify(
4491 server_ctx.get(), SSL_VERIFY_PEER,
4492 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4493 return ssl_verify_ok;
4494 });
4495
4496 bool cert_cb_called = false;
4497 SSL_CTX_set_cert_cb(
4498 client_ctx.get(),
4499 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04004500 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04004501 SSL_get0_server_requested_CAs(ssl);
4502 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
4503 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
4504 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
4505 CRYPTO_BUFFER_len(peer_name)));
4506 *reinterpret_cast<bool *>(arg) = true;
4507 return 1;
4508 },
4509 &cert_cb_called);
4510
4511 bssl::UniquePtr<SSL> client, server;
4512 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004513 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04004514 EXPECT_TRUE(cert_cb_called);
4515}
4516
David Benjamin91222b82017-03-09 20:10:56 -05004517// Configuring the empty cipher list, though an error, should still modify the
4518// configuration.
4519TEST(SSLTest, EmptyCipherList) {
4520 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4521 ASSERT_TRUE(ctx);
4522
4523 // Initially, the cipher list is not empty.
4524 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4525
4526 // Configuring the empty cipher list fails.
4527 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4528 ERR_clear_error();
4529
4530 // But the cipher list is still updated to empty.
4531 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4532}
4533
Adam Langley4c341d02017-03-08 19:33:21 -08004534// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4535// test |SSL_TICKET_AEAD_METHOD| can fail.
4536enum ssl_test_ticket_aead_failure_mode {
4537 ssl_test_ticket_aead_ok = 0,
4538 ssl_test_ticket_aead_seal_fail,
4539 ssl_test_ticket_aead_open_soft_fail,
4540 ssl_test_ticket_aead_open_hard_fail,
4541};
4542
4543struct ssl_test_ticket_aead_state {
4544 unsigned retry_count;
4545 ssl_test_ticket_aead_failure_mode failure_mode;
4546};
4547
4548static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4549 const CRYPTO_EX_DATA *from,
4550 void **from_d, int index,
4551 long argl, void *argp) {
4552 abort();
4553}
4554
4555static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4556 CRYPTO_EX_DATA *ad, int index,
4557 long argl, void *argp) {
4558 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4559 if (state == nullptr) {
4560 return;
4561 }
4562
4563 OPENSSL_free(state);
4564}
4565
4566static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4567static int g_ssl_test_ticket_aead_ex_index;
4568
4569static int ssl_test_ticket_aead_get_ex_index() {
4570 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4571 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4572 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4573 ssl_test_ticket_aead_ex_index_free);
4574 });
4575 return g_ssl_test_ticket_aead_ex_index;
4576}
4577
4578static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4579 return 1;
4580}
4581
4582static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4583 size_t max_out_len, const uint8_t *in,
4584 size_t in_len) {
4585 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4586 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4587
4588 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4589 max_out_len < in_len + 1) {
4590 return 0;
4591 }
4592
4593 OPENSSL_memmove(out, in, in_len);
4594 out[in_len] = 0xff;
4595 *out_len = in_len + 1;
4596
4597 return 1;
4598}
4599
4600static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4601 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4602 const uint8_t *in, size_t in_len) {
4603 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4604 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4605
4606 if (state->retry_count > 0) {
4607 state->retry_count--;
4608 return ssl_ticket_aead_retry;
4609 }
4610
4611 switch (state->failure_mode) {
4612 case ssl_test_ticket_aead_ok:
4613 break;
4614 case ssl_test_ticket_aead_seal_fail:
4615 // If |seal| failed then there shouldn't be any ticket to try and
4616 // decrypt.
4617 abort();
4618 break;
4619 case ssl_test_ticket_aead_open_soft_fail:
4620 return ssl_ticket_aead_ignore_ticket;
4621 case ssl_test_ticket_aead_open_hard_fail:
4622 return ssl_ticket_aead_error;
4623 }
4624
4625 if (in_len == 0 || in[in_len - 1] != 0xff) {
4626 return ssl_ticket_aead_ignore_ticket;
4627 }
4628
4629 if (max_out_len < in_len - 1) {
4630 return ssl_ticket_aead_error;
4631 }
4632
4633 OPENSSL_memmove(out, in, in_len - 1);
4634 *out_len = in_len - 1;
4635 return ssl_ticket_aead_success;
4636}
4637
4638static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4639 ssl_test_ticket_aead_max_overhead,
4640 ssl_test_ticket_aead_seal,
4641 ssl_test_ticket_aead_open,
4642};
4643
4644static void ConnectClientAndServerWithTicketMethod(
4645 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4646 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4647 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4648 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4649 ASSERT_TRUE(client);
4650 ASSERT_TRUE(server);
4651 SSL_set_connect_state(client.get());
4652 SSL_set_accept_state(server.get());
4653
4654 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4655 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4656 ASSERT_TRUE(state);
4657 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4658 state->retry_count = retry_count;
4659 state->failure_mode = failure_mode;
4660
4661 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4662 state));
4663
4664 SSL_set_session(client.get(), session);
4665
4666 BIO *bio1, *bio2;
4667 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4668
4669 // SSL_set_bio takes ownership.
4670 SSL_set_bio(client.get(), bio1, bio1);
4671 SSL_set_bio(server.get(), bio2, bio2);
4672
4673 if (CompleteHandshakes(client.get(), server.get())) {
4674 *out_client = std::move(client);
4675 *out_server = std::move(server);
4676 } else {
4677 out_client->reset();
4678 out_server->reset();
4679 }
4680}
4681
David Benjaminc9775322018-04-13 16:39:12 -04004682using TicketAEADMethodParam =
4683 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4684
Adam Langley4c341d02017-03-08 19:33:21 -08004685class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004686 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004687
4688TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004689 bssl::UniquePtr<SSL_CTX> server_ctx =
4690 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004691 ASSERT_TRUE(server_ctx);
4692 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4693 ASSERT_TRUE(client_ctx);
4694
4695 const uint16_t version = testing::get<0>(GetParam());
4696 const unsigned retry_count = testing::get<1>(GetParam());
4697 const ssl_test_ticket_aead_failure_mode failure_mode =
4698 testing::get<2>(GetParam());
4699
Adam Langley4c341d02017-03-08 19:33:21 -08004700 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4701 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4702 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4703 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4704
4705 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4706 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4707 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4708 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004709 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004710
4711 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4712
4713 bssl::UniquePtr<SSL> client, server;
4714 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4715 server_ctx.get(), retry_count,
4716 failure_mode, nullptr);
4717 switch (failure_mode) {
4718 case ssl_test_ticket_aead_ok:
4719 case ssl_test_ticket_aead_open_hard_fail:
4720 case ssl_test_ticket_aead_open_soft_fail:
4721 ASSERT_TRUE(client);
4722 break;
4723 case ssl_test_ticket_aead_seal_fail:
4724 EXPECT_FALSE(client);
4725 return;
4726 }
4727 EXPECT_FALSE(SSL_session_reused(client.get()));
4728 EXPECT_FALSE(SSL_session_reused(server.get()));
4729
Steven Valdez777a2392019-02-21 11:30:47 -05004730 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004731 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004732 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4733 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004734 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004735 switch (failure_mode) {
4736 case ssl_test_ticket_aead_ok:
4737 ASSERT_TRUE(client);
4738 EXPECT_TRUE(SSL_session_reused(client.get()));
4739 EXPECT_TRUE(SSL_session_reused(server.get()));
4740 break;
4741 case ssl_test_ticket_aead_seal_fail:
4742 abort();
4743 break;
4744 case ssl_test_ticket_aead_open_hard_fail:
4745 EXPECT_FALSE(client);
4746 break;
4747 case ssl_test_ticket_aead_open_soft_fail:
4748 ASSERT_TRUE(client);
4749 EXPECT_FALSE(SSL_session_reused(client.get()));
4750 EXPECT_FALSE(SSL_session_reused(server.get()));
4751 }
4752}
4753
David Benjaminc9775322018-04-13 16:39:12 -04004754std::string TicketAEADMethodParamToString(
4755 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4756 std::string ret = GetVersionName(std::get<0>(params.param));
4757 // GTest only allows alphanumeric characters and '_' in the parameter
4758 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4759 for (auto it = ret.begin(); it != ret.end();) {
4760 if (*it == '.' || *it == 'v') {
4761 it = ret.erase(it);
4762 } else {
4763 ++it;
4764 }
4765 }
4766 char retry_count[256];
David Benjamin4f1fae32021-12-15 11:41:10 -05004767 snprintf(retry_count, sizeof(retry_count), "%u", std::get<1>(params.param));
David Benjaminc9775322018-04-13 16:39:12 -04004768 ret += "_";
4769 ret += retry_count;
4770 ret += "Retries_";
4771 switch (std::get<2>(params.param)) {
4772 case ssl_test_ticket_aead_ok:
4773 ret += "OK";
4774 break;
4775 case ssl_test_ticket_aead_seal_fail:
4776 ret += "SealFail";
4777 break;
4778 case ssl_test_ticket_aead_open_soft_fail:
4779 ret += "OpenSoftFail";
4780 break;
4781 case ssl_test_ticket_aead_open_hard_fail:
4782 ret += "OpenHardFail";
4783 break;
4784 }
4785 return ret;
4786}
4787
David Benjaminbe7006a2019-04-09 18:05:02 -05004788INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004789 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004790 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4791 testing::Values(0, 1, 2),
4792 testing::Values(ssl_test_ticket_aead_ok,
4793 ssl_test_ticket_aead_seal_fail,
4794 ssl_test_ticket_aead_open_soft_fail,
4795 ssl_test_ticket_aead_open_hard_fail)),
4796 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004797
David Benjaminca743582017-06-15 17:51:35 -04004798TEST(SSLTest, SelectNextProto) {
4799 uint8_t *result;
4800 uint8_t result_len;
4801
4802 // If there is an overlap, it should be returned.
4803 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4804 SSL_select_next_proto(&result, &result_len,
4805 (const uint8_t *)"\1a\2bb\3ccc", 9,
4806 (const uint8_t *)"\1x\1y\1a\1z", 8));
4807 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4808
4809 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4810 SSL_select_next_proto(&result, &result_len,
4811 (const uint8_t *)"\1a\2bb\3ccc", 9,
4812 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4813 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4814
4815 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4816 SSL_select_next_proto(&result, &result_len,
4817 (const uint8_t *)"\1a\2bb\3ccc", 9,
4818 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4819 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4820
4821 // Peer preference order takes precedence over local.
4822 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4823 SSL_select_next_proto(&result, &result_len,
4824 (const uint8_t *)"\1a\2bb\3ccc", 9,
4825 (const uint8_t *)"\3ccc\2bb\1a", 9));
4826 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4827
4828 // If there is no overlap, return the first local protocol.
4829 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4830 SSL_select_next_proto(&result, &result_len,
4831 (const uint8_t *)"\1a\2bb\3ccc", 9,
4832 (const uint8_t *)"\1x\2yy\3zzz", 9));
4833 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4834
4835 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4836 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4837 (const uint8_t *)"\1x\2yy\3zzz", 9));
4838 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4839}
4840
David Benjamin617b8182017-08-29 15:33:10 -04004841// The client should gracefully handle no suitable ciphers being enabled.
4842TEST(SSLTest, NoCiphersAvailable) {
4843 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4844 ASSERT_TRUE(ctx);
4845
4846 // Configure |client_ctx| with a cipher list that does not intersect with its
4847 // version configuration.
4848 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4849 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4850 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4851
4852 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4853 ASSERT_TRUE(ssl);
4854 SSL_set_connect_state(ssl.get());
4855
4856 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4857 ASSERT_TRUE(rbio);
4858 ASSERT_TRUE(wbio);
4859 SSL_set0_rbio(ssl.get(), rbio.release());
4860 SSL_set0_wbio(ssl.get(), wbio.release());
4861
4862 int ret = SSL_do_handshake(ssl.get());
4863 EXPECT_EQ(-1, ret);
4864 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4865 uint32_t err = ERR_get_error();
4866 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4867 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4868}
4869
David Benjamina4bafd32017-10-03 15:06:29 -04004870TEST_P(SSLVersionTest, SessionVersion) {
4871 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4872 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4873
4874 bssl::UniquePtr<SSL_SESSION> session =
4875 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4876 ASSERT_TRUE(session);
4877 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4878
4879 // Sessions in TLS 1.3 and later should be single-use.
4880 EXPECT_EQ(version() == TLS1_3_VERSION,
4881 !!SSL_SESSION_should_be_single_use(session.get()));
4882
4883 // Making fake sessions for testing works.
4884 session.reset(SSL_SESSION_new(client_ctx_.get()));
4885 ASSERT_TRUE(session);
4886 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4887 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4888}
4889
David Benjaminfdb7a352017-10-12 17:34:18 -04004890TEST_P(SSLVersionTest, SSLPending) {
4891 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4892 ASSERT_TRUE(ssl);
4893 EXPECT_EQ(0, SSL_pending(ssl.get()));
4894
4895 ASSERT_TRUE(Connect());
4896 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004897 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004898
4899 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4900 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4901 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004902 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004903
4904 char buf[10];
4905 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4906 EXPECT_EQ(5, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004907 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004908
4909 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4910 EXPECT_EQ(4, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004911 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004912
4913 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4914 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004915 if (is_dtls()) {
4916 // In DTLS, the two records would have been read as a single datagram and
4917 // buffered inside |client_|. Thus, |SSL_has_pending| should return true.
4918 //
4919 // This test is slightly unrealistic. It relies on |ConnectClientAndServer|
4920 // using a |BIO| pair, which does not preserve datagram boundaries. Reading
4921 // 1 byte, then 4 bytes, from the first record also relies on
4922 // https://crbug.com/boringssl/65. But it does test the codepaths. When
4923 // fixing either of these bugs, this test may need to be redone.
4924 EXPECT_EQ(1, SSL_has_pending(client_.get()));
4925 } else {
4926 // In TLS, we do not overread, so |SSL_has_pending| should report no data is
4927 // buffered.
4928 EXPECT_EQ(0, SSL_has_pending(client_.get()));
4929 }
David Benjaminfdb7a352017-10-12 17:34:18 -04004930
4931 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4932 EXPECT_EQ(3, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05004933 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04004934}
4935
David Benjamina031b612017-10-11 20:48:25 -04004936// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4937TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004938 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004939 ASSERT_TRUE(ctx);
4940 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4941 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4942
David Benjamina031b612017-10-11 20:48:25 -04004943 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4944
4945 bssl::UniquePtr<SSL> client, server;
4946 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4947
4948 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4949 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4950 return 0;
4951 });
4952
4953 // Send close_notify.
4954 EXPECT_EQ(0, SSL_shutdown(server.get()));
4955 EXPECT_EQ(0, SSL_shutdown(client.get()));
4956
4957 // Receive close_notify.
4958 EXPECT_EQ(1, SSL_shutdown(server.get()));
4959 EXPECT_EQ(1, SSL_shutdown(client.get()));
4960}
4961
David Benjamin6cc352e2017-11-02 17:21:39 -04004962TEST(SSLTest, SignatureAlgorithmProperties) {
4963 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4964 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4965 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4966
4967 EXPECT_EQ(EVP_PKEY_RSA,
4968 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4969 EXPECT_EQ(EVP_md5_sha1(),
4970 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4971 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4972
4973 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4974 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4975 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4976 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4977 EXPECT_FALSE(
4978 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4979
4980 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004981 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004982 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004983 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4984 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004985}
4986
Adam Langley85967952018-07-03 08:04:58 -07004987static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4988 size_t in_len) {
4989 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004990 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004991 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004992 }
4993 }
4994
4995 SSL_set_app_data(ssl, XORCompressFunc);
4996
Adam Langley85967952018-07-03 08:04:58 -07004997 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004998}
4999
Adam Langley85967952018-07-03 08:04:58 -07005000static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
5001 size_t uncompressed_len, const uint8_t *in,
5002 size_t in_len) {
5003 if (in_len != uncompressed_len) {
5004 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005005 }
5006
5007 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07005008 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
5009 if (*out == nullptr) {
5010 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005011 }
5012
Adam Langley85967952018-07-03 08:04:58 -07005013 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005014 data[i] = in[i] ^ 0x55;
5015 }
5016
5017 SSL_set_app_data(ssl, XORDecompressFunc);
5018
Adam Langley85967952018-07-03 08:04:58 -07005019 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005020}
5021
5022TEST(SSLTest, CertCompression) {
5023 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005024 bssl::UniquePtr<SSL_CTX> server_ctx(
5025 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07005026 ASSERT_TRUE(client_ctx);
5027 ASSERT_TRUE(server_ctx);
5028
Adam Langley0080d832018-06-07 16:39:49 -07005029 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5030 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5031 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5032 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5033 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5034 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5035
5036 bssl::UniquePtr<SSL> client, server;
5037 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5038 server_ctx.get()));
5039
5040 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
5041 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
5042}
5043
Adam Langleyddb57cf2018-01-26 09:17:53 -08005044void MoveBIOs(SSL *dest, SSL *src) {
5045 BIO *rbio = SSL_get_rbio(src);
5046 BIO_up_ref(rbio);
5047 SSL_set0_rbio(dest, rbio);
5048
5049 BIO *wbio = SSL_get_wbio(src);
5050 BIO_up_ref(wbio);
5051 SSL_set0_wbio(dest, wbio);
5052
5053 SSL_set0_rbio(src, nullptr);
5054 SSL_set0_wbio(src, nullptr);
5055}
5056
5057TEST(SSLTest, Handoff) {
5058 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5059 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005060 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
5061 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005062 ASSERT_TRUE(client_ctx);
5063 ASSERT_TRUE(server_ctx);
5064 ASSERT_TRUE(handshaker_ctx);
5065
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005066 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
5067 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005068 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005069 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05005070 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005071 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005072
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005073 for (bool early_data : {false, true}) {
5074 SCOPED_TRACE(early_data);
5075 for (bool is_resume : {false, true}) {
5076 SCOPED_TRACE(is_resume);
5077 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005078 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5079 server_ctx.get()));
5080 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005081 if (is_resume) {
5082 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04005083 SSL_set_session(client.get(), g_last_session.get());
5084 if (early_data) {
5085 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
5086 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005087 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04005088
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005089
5090 int client_ret = SSL_do_handshake(client.get());
5091 int client_err = SSL_get_error(client.get(), client_ret);
5092
5093 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005094 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005095 ASSERT_EQ(client_err, 0);
5096 EXPECT_TRUE(SSL_in_early_data(client.get()));
5097 // Attempt to write early data.
5098 byte_written = 43;
5099 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5100 } else {
5101 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5102 }
5103
5104 int server_ret = SSL_do_handshake(server.get());
5105 int server_err = SSL_get_error(server.get(), server_ret);
5106 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5107
5108 ScopedCBB cbb;
5109 Array<uint8_t> handoff;
5110 SSL_CLIENT_HELLO hello;
5111 ASSERT_TRUE(CBB_init(cbb.get(), 256));
5112 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5113 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5114
5115 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
5116 // Note split handshakes determines 0-RTT support, for both the current
5117 // handshake and newly-issued tickets, entirely by |handshaker|. There is
5118 // no need to call |SSL_set_early_data_enabled| on |server|.
5119 SSL_set_early_data_enabled(handshaker.get(), 1);
5120 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5121
5122 MoveBIOs(handshaker.get(), server.get());
5123
5124 int handshake_ret = SSL_do_handshake(handshaker.get());
5125 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5126 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5127
5128 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08005129 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005130 handshake_ret = SSL_do_handshake(handshaker.get());
5131 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5132 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5133
5134 ScopedCBB cbb_handback;
5135 Array<uint8_t> handback;
5136 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5137 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5138 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5139
5140 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
5141 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5142
5143 MoveBIOs(server2.get(), handshaker.get());
5144 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5145 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
5146
David Benjamin9b2cdb72021-04-01 23:21:53 -04005147 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005148 // In this case, one byte of early data has already been written above.
5149 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5150 } else {
5151 byte_written = 42;
5152 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5153 }
5154 uint8_t byte;
5155 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5156 EXPECT_EQ(byte_written, byte);
5157
5158 byte = 44;
5159 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5160 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5161 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005162 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005163 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08005164}
5165
5166TEST(SSLTest, HandoffDeclined) {
5167 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005168 bssl::UniquePtr<SSL_CTX> server_ctx(
5169 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005170 ASSERT_TRUE(client_ctx);
5171 ASSERT_TRUE(server_ctx);
5172
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005173 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Adam Langleyddb57cf2018-01-26 09:17:53 -08005174 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5175
Adam Langleyddb57cf2018-01-26 09:17:53 -08005176 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005177 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5178 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005179
5180 int client_ret = SSL_do_handshake(client.get());
5181 int client_err = SSL_get_error(client.get(), client_ret);
5182 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5183
5184 int server_ret = SSL_do_handshake(server.get());
5185 int server_err = SSL_get_error(server.get(), server_ret);
5186 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5187
5188 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005189 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005190 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005191 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005192
5193 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5194
5195 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5196
5197 uint8_t byte = 42;
5198 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5199 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5200 EXPECT_EQ(42, byte);
5201
5202 byte = 43;
5203 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5204 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5205 EXPECT_EQ(43, byte);
5206}
5207
Adam Langley826ce152018-08-03 10:31:21 -07005208static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5209 std::string ret = "{";
5210
5211 for (uint16_t v : sigalgs) {
5212 if (ret.size() > 1) {
5213 ret += ", ";
5214 }
5215
5216 char buf[8];
5217 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5218 buf[sizeof(buf)-1] = 0;
5219 ret += std::string(buf);
5220 }
5221
5222 ret += "}";
5223 return ret;
5224}
5225
5226void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5227 Span<const uint16_t> actual) {
5228 bool matches = false;
5229 if (expected.size() == actual.size()) {
5230 matches = true;
5231
5232 for (size_t i = 0; i < expected.size(); i++) {
5233 if (expected[i] != actual[i]) {
5234 matches = false;
5235 break;
5236 }
5237 }
5238 }
5239
5240 if (!matches) {
5241 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5242 << " got: " << SigAlgsToString(actual);
5243 }
5244}
5245
5246TEST(SSLTest, SigAlgs) {
5247 static const struct {
5248 std::vector<int> input;
5249 bool ok;
5250 std::vector<uint16_t> expected;
5251 } kTests[] = {
5252 {{}, true, {}},
5253 {{1}, false, {}},
5254 {{1, 2, 3}, false, {}},
5255 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5256 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5257
5258 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5259 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5260 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5261 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5262 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5263 true,
5264 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5265 };
5266
5267 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5268
5269 unsigned n = 1;
5270 for (const auto &test : kTests) {
5271 SCOPED_TRACE(n++);
5272
5273 const bool ok =
5274 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5275 EXPECT_EQ(ok, test.ok);
5276
5277 if (!ok) {
5278 ERR_clear_error();
5279 }
5280
5281 if (!test.ok) {
5282 continue;
5283 }
5284
5285 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5286 }
5287}
5288
5289TEST(SSLTest, SigAlgsList) {
5290 static const struct {
5291 const char *input;
5292 bool ok;
5293 std::vector<uint16_t> expected;
5294 } kTests[] = {
5295 {"", false, {}},
5296 {":", false, {}},
5297 {"+", false, {}},
5298 {"RSA", false, {}},
5299 {"RSA+", false, {}},
5300 {"RSA+SHA256:", false, {}},
5301 {":RSA+SHA256:", false, {}},
5302 {":RSA+SHA256+:", false, {}},
5303 {"!", false, {}},
5304 {"\x01", false, {}},
5305 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5306 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5307
5308 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5309 {"RSA+SHA256:ed25519",
5310 true,
5311 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5312 {"ECDSA+SHA256:RSA+SHA512",
5313 true,
5314 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5315 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5316 true,
5317 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5318 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5319 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5320 };
5321
5322 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5323
5324 unsigned n = 1;
5325 for (const auto &test : kTests) {
5326 SCOPED_TRACE(n++);
5327
5328 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5329 EXPECT_EQ(ok, test.ok);
5330
5331 if (!ok) {
5332 if (test.ok) {
5333 ERR_print_errors_fp(stderr);
5334 }
5335 ERR_clear_error();
5336 }
5337
5338 if (!test.ok) {
5339 continue;
5340 }
5341
5342 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5343 }
5344}
5345
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005346TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5347 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5348 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5349
5350 // handoff is a handoff message that has been artificially modified to pretend
5351 // that only cipher 0x0A is supported. When it is applied to |server|, all
5352 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005353 //
5354 // To make a new one of these, try sticking this in the |Handoff| test above:
5355 //
5356 // hexdump(stderr, "", handoff.data(), handoff.size());
5357 // sed -e 's/\(..\)/0x\1, /g'
5358 //
5359 // and modify serialize_features() to emit only cipher 0x0A.
5360
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005361 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005362 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5363 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5364 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5365 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5366 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005367 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5368 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005369 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5370 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5371 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5372 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5373 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
5374 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5375 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005376 };
5377
5378 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5379 ASSERT_TRUE(
5380 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5381 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5382}
5383
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005384TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5385 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5386 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5387
5388 // handoff is a handoff message that has been artificially modified to pretend
5389 // that only one curve is supported. When it is applied to |server|, all
5390 // curves but that one should be removed.
5391 //
5392 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5393 // these.
5394 uint8_t handoff[] = {
5395 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5396 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5397 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5398 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5399 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5400 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5401 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5402 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5403 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5404 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5405 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5406 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5407 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5408 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5409 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5410 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5411 0x02, 0x00, 0x17,
5412 };
5413
5414 // The zero length means that the default list of groups is used.
5415 EXPECT_EQ(0u, server->config->supported_group_list.size());
5416 ASSERT_TRUE(
5417 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5418 EXPECT_EQ(1u, server->config->supported_group_list.size());
5419}
5420
Adam Langleyba9ad662018-12-17 13:59:38 -08005421TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5422 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5423 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005424 bssl::UniquePtr<SSL_CTX> server_ctx(
5425 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005426 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5427 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005428
5429 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5430 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5431 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5432
5433 bssl::UniquePtr<SSL> client, server;
5434 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5435 server_ctx.get()));
5436
5437 BIO *client_wbio = SSL_get_wbio(client.get());
5438 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5439 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5440 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5441 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5442 EXPECT_NE(0u, BIO_wpending(client_wbio));
5443}
5444
David Benjamin5869eb32018-07-17 00:59:45 -04005445TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5446 // Configure the server to request client certificates.
5447 SSL_CTX_set_custom_verify(
5448 server_ctx_.get(), SSL_VERIFY_PEER,
5449 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5450
5451 // Configure the client to reject the server certificate.
5452 SSL_CTX_set_custom_verify(
5453 client_ctx_.get(), SSL_VERIFY_PEER,
5454 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5455
5456 // cert_cb should not be called. Verification should fail first.
5457 SSL_CTX_set_cert_cb(client_ctx_.get(),
5458 [](SSL *ssl, void *arg) {
5459 ADD_FAILURE() << "cert_cb unexpectedly called";
5460 return 0;
5461 },
5462 nullptr);
5463
5464 bssl::UniquePtr<SSL> client, server;
5465 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5466 server_ctx_.get()));
5467}
5468
David Benjamin492c9aa2018-08-31 16:35:22 -05005469// Test that ticket-based sessions on the client get fake session IDs.
5470TEST_P(SSLVersionTest, FakeIDsForTickets) {
5471 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5472 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5473
5474 bssl::UniquePtr<SSL_SESSION> session =
5475 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5476 ASSERT_TRUE(session);
5477
5478 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5479 unsigned session_id_length;
5480 SSL_SESSION_get_id(session.get(), &session_id_length);
5481 EXPECT_NE(session_id_length, 0u);
5482}
5483
David Benjamin6c04bd12018-07-19 18:13:09 -04005484// These tests test multi-threaded behavior. They are intended to run with
5485// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005486#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005487TEST_P(SSLVersionTest, SessionCacheThreads) {
5488 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5489 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5490 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5491
5492 if (version() == TLS1_3_VERSION) {
5493 // Our TLS 1.3 implementation does not support stateful resumption.
5494 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5495 return;
5496 }
5497
5498 // Establish two client sessions to test with.
5499 bssl::UniquePtr<SSL_SESSION> session1 =
5500 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5501 ASSERT_TRUE(session1);
5502 bssl::UniquePtr<SSL_SESSION> session2 =
5503 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5504 ASSERT_TRUE(session2);
5505
5506 auto connect_with_session = [&](SSL_SESSION *session) {
5507 ClientConfig config;
5508 config.session = session;
5509 UniquePtr<SSL> client, server;
5510 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5511 server_ctx_.get(), config));
5512 };
5513
5514 // Resume sessions in parallel with establishing new ones.
5515 {
5516 std::vector<std::thread> threads;
5517 threads.emplace_back([&] { connect_with_session(nullptr); });
5518 threads.emplace_back([&] { connect_with_session(nullptr); });
5519 threads.emplace_back([&] { connect_with_session(session1.get()); });
5520 threads.emplace_back([&] { connect_with_session(session1.get()); });
5521 threads.emplace_back([&] { connect_with_session(session2.get()); });
5522 threads.emplace_back([&] { connect_with_session(session2.get()); });
5523 for (auto &thread : threads) {
5524 thread.join();
5525 }
5526 }
5527
David Benjamina10017c2021-06-16 16:00:13 -04005528 // Hit the maximum session cache size across multiple threads, to test the
5529 // size enforcement logic.
David Benjamin6c04bd12018-07-19 18:13:09 -04005530 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5531 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5532 {
5533 std::vector<std::thread> threads;
5534 for (int i = 0; i < 4; i++) {
5535 threads.emplace_back([&]() {
5536 connect_with_session(nullptr);
5537 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5538 });
5539 }
5540 for (auto &thread : threads) {
5541 thread.join();
5542 }
5543 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5544 }
David Benjamina10017c2021-06-16 16:00:13 -04005545
5546 // Reset the session cache, this time with a mock clock.
5547 ASSERT_NO_FATAL_FAILURE(ResetContexts());
5548 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5549 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5550 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5551 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
5552
5553 // Make some sessions at an arbitrary start time. Then expire them.
5554 g_current_time.tv_sec = 1000;
5555 bssl::UniquePtr<SSL_SESSION> expired_session1 =
5556 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5557 ASSERT_TRUE(expired_session1);
5558 bssl::UniquePtr<SSL_SESSION> expired_session2 =
5559 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5560 ASSERT_TRUE(expired_session2);
5561 g_current_time.tv_sec += 100 * SSL_DEFAULT_SESSION_TIMEOUT;
5562
5563 session1 = CreateClientSession(client_ctx_.get(), server_ctx_.get());
5564 ASSERT_TRUE(session1);
5565
5566 // Every 256 connections, we flush stale sessions from the session cache. Test
5567 // this logic is correctly synchronized with other connection attempts.
5568 static const int kNumConnections = 256;
5569 {
5570 std::vector<std::thread> threads;
5571 threads.emplace_back([&] {
5572 for (int i = 0; i < kNumConnections; i++) {
5573 connect_with_session(nullptr);
5574 }
5575 });
5576 threads.emplace_back([&] {
5577 for (int i = 0; i < kNumConnections; i++) {
5578 connect_with_session(nullptr);
5579 }
5580 });
5581 threads.emplace_back([&] {
5582 // Never connect with |expired_session2|. The session cache eagerly
5583 // removes expired sessions when it sees them. Leaving |expired_session2|
5584 // untouched ensures it is instead cleared by periodic flushing.
5585 for (int i = 0; i < kNumConnections; i++) {
5586 connect_with_session(expired_session1.get());
5587 }
5588 });
5589 threads.emplace_back([&] {
5590 for (int i = 0; i < kNumConnections; i++) {
5591 connect_with_session(session1.get());
5592 }
5593 });
5594 for (auto &thread : threads) {
5595 thread.join();
5596 }
5597 }
David Benjamin6c04bd12018-07-19 18:13:09 -04005598}
5599
5600TEST_P(SSLVersionTest, SessionTicketThreads) {
5601 for (bool renew_ticket : {false, true}) {
5602 SCOPED_TRACE(renew_ticket);
5603 ResetContexts();
5604 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5605 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5606 if (renew_ticket) {
5607 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5608 }
5609
5610 // Establish two client sessions to test with.
5611 bssl::UniquePtr<SSL_SESSION> session1 =
5612 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5613 ASSERT_TRUE(session1);
5614 bssl::UniquePtr<SSL_SESSION> session2 =
5615 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5616 ASSERT_TRUE(session2);
5617
5618 auto connect_with_session = [&](SSL_SESSION *session) {
5619 ClientConfig config;
5620 config.session = session;
5621 UniquePtr<SSL> client, server;
5622 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5623 server_ctx_.get(), config));
5624 };
5625
5626 // Resume sessions in parallel with establishing new ones.
5627 {
5628 std::vector<std::thread> threads;
5629 threads.emplace_back([&] { connect_with_session(nullptr); });
5630 threads.emplace_back([&] { connect_with_session(nullptr); });
5631 threads.emplace_back([&] { connect_with_session(session1.get()); });
5632 threads.emplace_back([&] { connect_with_session(session1.get()); });
5633 threads.emplace_back([&] { connect_with_session(session2.get()); });
5634 threads.emplace_back([&] { connect_with_session(session2.get()); });
5635 for (auto &thread : threads) {
5636 thread.join();
5637 }
5638 }
5639 }
5640}
5641
5642// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5643TEST(SSLTest, GetCertificateThreads) {
5644 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5645 ASSERT_TRUE(ctx);
5646 bssl::UniquePtr<X509> cert = GetTestCertificate();
5647 ASSERT_TRUE(cert);
5648 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5649
5650 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5651 // threads concurrently. It originally was an immutable operation. Now we
5652 // implement it with a thread-safe cache, so it is worth testing.
5653 X509 *cert2_thread;
5654 std::thread thread(
5655 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5656 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5657 thread.join();
5658
5659 EXPECT_EQ(cert2, cert2_thread);
5660 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5661}
David Benjamin4cce9552018-12-13 12:20:54 -06005662
5663// Functions which access properties on the negotiated session are thread-safe
5664// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5665// performing stateful resumption will share an underlying SSL_SESSION object,
5666// potentially across threads.
5667TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5668 if (version() == TLS1_3_VERSION) {
5669 // Our TLS 1.3 implementation does not support stateful resumption.
5670 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5671 return;
5672 }
5673
5674 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5675 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5676 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5677
5678 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5679 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5680
5681 // Configure mutual authentication, so we have more session state.
5682 SSL_CTX_set_custom_verify(
5683 client_ctx_.get(), SSL_VERIFY_PEER,
5684 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5685 SSL_CTX_set_custom_verify(
5686 server_ctx_.get(), SSL_VERIFY_PEER,
5687 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5688
5689 // Establish a client session to test with.
5690 bssl::UniquePtr<SSL_SESSION> session =
5691 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5692 ASSERT_TRUE(session);
5693
5694 // Resume with it twice.
5695 UniquePtr<SSL> ssls[4];
5696 ClientConfig config;
5697 config.session = session.get();
5698 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5699 server_ctx_.get(), config));
5700 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5701 server_ctx_.get(), config));
5702
5703 // Read properties in parallel.
5704 auto read_properties = [](const SSL *ssl) {
5705 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5706 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5707 EXPECT_TRUE(peer);
5708 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5709 EXPECT_TRUE(SSL_get_curve_id(ssl));
5710 };
5711
5712 std::vector<std::thread> threads;
5713 for (const auto &ssl_ptr : ssls) {
5714 const SSL *ssl = ssl_ptr.get();
5715 threads.emplace_back([=] { read_properties(ssl); });
5716 }
5717 for (auto &thread : threads) {
5718 thread.join();
5719 }
5720}
David Benjamina486c6c2019-03-28 18:32:38 -05005721#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005722
Steven Valdezc8e0f902018-07-14 11:23:01 -04005723constexpr size_t kNumQUICLevels = 4;
5724static_assert(ssl_encryption_initial < kNumQUICLevels,
5725 "kNumQUICLevels is wrong");
5726static_assert(ssl_encryption_early_data < kNumQUICLevels,
5727 "kNumQUICLevels is wrong");
5728static_assert(ssl_encryption_handshake < kNumQUICLevels,
5729 "kNumQUICLevels is wrong");
5730static_assert(ssl_encryption_application < kNumQUICLevels,
5731 "kNumQUICLevels is wrong");
5732
David Benjamin1e859052020-02-09 16:04:58 -05005733const char *LevelToString(ssl_encryption_level_t level) {
5734 switch (level) {
5735 case ssl_encryption_initial:
5736 return "initial";
5737 case ssl_encryption_early_data:
5738 return "early data";
5739 case ssl_encryption_handshake:
5740 return "handshake";
5741 case ssl_encryption_application:
5742 return "application";
5743 }
5744 return "<unknown>";
5745}
5746
Steven Valdezc8e0f902018-07-14 11:23:01 -04005747class MockQUICTransport {
5748 public:
David Benjamind6343572019-08-15 17:29:02 -04005749 enum class Role { kClient, kServer };
5750
5751 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005752 // The caller is expected to configure initial secrets.
5753 levels_[ssl_encryption_initial].write_secret = {1};
5754 levels_[ssl_encryption_initial].read_secret = {1};
5755 }
5756
5757 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5758
5759 bool has_alert() const { return has_alert_; }
5760 ssl_encryption_level_t alert_level() const { return alert_level_; }
5761 uint8_t alert() const { return alert_; }
5762
5763 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5764 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005765 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5766 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005767 }
5768
David Benjamin1e859052020-02-09 16:04:58 -05005769 bool HasReadSecret(ssl_encryption_level_t level) const {
5770 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005771 }
5772
David Benjamin1e859052020-02-09 16:04:58 -05005773 bool HasWriteSecret(ssl_encryption_level_t level) const {
5774 return !levels_[level].write_secret.empty();
5775 }
5776
David Benjamin5298ef92020-03-13 12:17:30 -04005777 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5778
David Benjamin1e859052020-02-09 16:04:58 -05005779 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5780 Span<const uint8_t> secret) {
5781 if (HasReadSecret(level)) {
5782 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5783 return false;
5784 }
5785
5786 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5787 ADD_FAILURE() << "Unexpected early data read secret";
5788 return false;
5789 }
5790
5791 ssl_encryption_level_t ack_level =
5792 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5793 if (!HasWriteSecret(ack_level)) {
5794 ADD_FAILURE() << LevelToString(level)
5795 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005796 return false;
5797 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005798
5799 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005800 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005801 return false;
5802 }
5803
David Benjamin1e859052020-02-09 16:04:58 -05005804 if (level != ssl_encryption_early_data &&
5805 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5806 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005807 return false;
5808 }
David Benjamind6343572019-08-15 17:29:02 -04005809
David Benjamin1e859052020-02-09 16:04:58 -05005810 levels_[level].read_secret.assign(secret.begin(), secret.end());
5811 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5812 return true;
5813 }
5814
5815 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5816 Span<const uint8_t> secret) {
5817 if (HasWriteSecret(level)) {
5818 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005819 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005820 }
David Benjamind6343572019-08-15 17:29:02 -04005821
David Benjamin1e859052020-02-09 16:04:58 -05005822 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5823 ADD_FAILURE() << "Unexpected early data write secret";
5824 return false;
5825 }
5826
5827 if (cipher == nullptr) {
5828 ADD_FAILURE() << "Unexpected null cipher";
5829 return false;
5830 }
5831
5832 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005833 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005834 return true;
5835 }
5836
5837 bool WriteHandshakeData(ssl_encryption_level_t level,
5838 Span<const uint8_t> data) {
5839 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005840 ADD_FAILURE() << LevelToString(level)
5841 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005842 return false;
5843 }
David Benjamin5298ef92020-03-13 12:17:30 -04005844
5845 // Although the levels are conceptually separate, BoringSSL finishes writing
5846 // data from a previous level before installing keys for the next level.
5847 if (!allow_out_of_order_writes_) {
5848 switch (level) {
5849 case ssl_encryption_early_data:
5850 ADD_FAILURE() << "unexpected handshake data at early data level";
5851 return false;
5852 case ssl_encryption_initial:
5853 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5854 ADD_FAILURE()
5855 << LevelToString(level)
5856 << " handshake data written after handshake keys installed";
5857 return false;
5858 }
5859 OPENSSL_FALLTHROUGH;
5860 case ssl_encryption_handshake:
5861 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5862 ADD_FAILURE()
5863 << LevelToString(level)
5864 << " handshake data written after application keys installed";
5865 return false;
5866 }
5867 OPENSSL_FALLTHROUGH;
5868 case ssl_encryption_application:
5869 break;
5870 }
5871 }
5872
Steven Valdezc8e0f902018-07-14 11:23:01 -04005873 levels_[level].write_data.insert(levels_[level].write_data.end(),
5874 data.begin(), data.end());
5875 return true;
5876 }
5877
5878 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5879 if (has_alert_) {
5880 ADD_FAILURE() << "duplicate alert sent";
5881 return false;
5882 }
5883
5884 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005885 ADD_FAILURE() << LevelToString(level)
5886 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005887 return false;
5888 }
5889
5890 has_alert_ = true;
5891 alert_level_ = level;
5892 alert_ = alert_value;
5893 return true;
5894 }
5895
5896 bool ReadHandshakeData(std::vector<uint8_t> *out,
5897 ssl_encryption_level_t level,
5898 size_t num = std::numeric_limits<size_t>::max()) {
5899 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005900 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005901 return false;
5902 }
5903 // The peer may not have configured any keys yet.
5904 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005905 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005906 return true;
5907 }
5908 // Check the peer computed the same key.
5909 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005910 ADD_FAILURE() << "peer write key does not match read key in level "
5911 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005912 return false;
5913 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005914 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005915 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005916 return false;
5917 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005918 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5919 num = std::min(num, peer_data->size());
5920 out->assign(peer_data->begin(), peer_data->begin() + num);
5921 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5922 return true;
5923 }
5924
5925 private:
David Benjamind6343572019-08-15 17:29:02 -04005926 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005927 MockQUICTransport *peer_ = nullptr;
5928
David Benjamin5298ef92020-03-13 12:17:30 -04005929 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005930 bool has_alert_ = false;
5931 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5932 uint8_t alert_ = 0;
5933
5934 struct Level {
5935 std::vector<uint8_t> write_data;
5936 std::vector<uint8_t> write_secret;
5937 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005938 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005939 };
5940 Level levels_[kNumQUICLevels];
5941};
5942
5943class MockQUICTransportPair {
5944 public:
David Benjamind6343572019-08-15 17:29:02 -04005945 MockQUICTransportPair()
5946 : client_(MockQUICTransport::Role::kClient),
5947 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005948 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005949 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005950 }
5951
5952 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005953 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005954 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005955 }
5956
5957 MockQUICTransport *client() { return &client_; }
5958 MockQUICTransport *server() { return &server_; }
5959
5960 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005961 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5962 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5963 return client_.PeerSecretsMatch(level) &&
5964 client_.HasWriteSecret(level) &&
5965 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005966 }
5967
5968 private:
5969 MockQUICTransport client_;
5970 MockQUICTransport server_;
5971};
5972
5973class QUICMethodTest : public testing::Test {
5974 protected:
5975 void SetUp() override {
5976 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005977 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005978 ASSERT_TRUE(client_ctx_);
5979 ASSERT_TRUE(server_ctx_);
5980
Steven Valdezc8e0f902018-07-14 11:23:01 -04005981 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5982 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5983 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5984 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005985
5986 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5987 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5988 sizeof(kALPNProtos)),
5989 0);
5990 SSL_CTX_set_alpn_select_cb(
5991 server_ctx_.get(),
5992 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5993 unsigned in_len, void *arg) -> int {
5994 return SSL_select_next_proto(
5995 const_cast<uint8_t **>(out), out_len, in, in_len,
5996 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5997 ? SSL_TLSEXT_ERR_OK
5998 : SSL_TLSEXT_ERR_NOACK;
5999 },
6000 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006001 }
6002
6003 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
6004 return ex_data_.Get(ssl);
6005 }
6006
6007 static bool ProvideHandshakeData(
6008 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
6009 MockQUICTransport *transport = TransportFromSSL(ssl);
6010 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
6011 std::vector<uint8_t> data;
6012 return transport->ReadHandshakeData(&data, level, num) &&
6013 SSL_provide_quic_data(ssl, level, data.data(), data.size());
6014 }
6015
David Benjamin5298ef92020-03-13 12:17:30 -04006016 void AllowOutOfOrderWrites() {
6017 allow_out_of_order_writes_ = true;
6018 }
6019
Steven Valdezc8e0f902018-07-14 11:23:01 -04006020 bool CreateClientAndServer() {
6021 client_.reset(SSL_new(client_ctx_.get()));
6022 server_.reset(SSL_new(server_ctx_.get()));
6023 if (!client_ || !server_) {
6024 return false;
6025 }
6026
6027 SSL_set_connect_state(client_.get());
6028 SSL_set_accept_state(server_.get());
6029
David Benjamind6343572019-08-15 17:29:02 -04006030 transport_.reset(new MockQUICTransportPair);
6031 ex_data_.Set(client_.get(), transport_->client());
6032 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04006033 if (allow_out_of_order_writes_) {
6034 transport_->client()->AllowOutOfOrderWrites();
6035 transport_->server()->AllowOutOfOrderWrites();
6036 }
Nick Harper7c522992020-04-30 14:15:49 -07006037 static const uint8_t client_transport_params[] = {0};
6038 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
6039 sizeof(client_transport_params)) ||
6040 !SSL_set_quic_transport_params(server_.get(),
6041 server_transport_params_.data(),
6042 server_transport_params_.size()) ||
6043 !SSL_set_quic_early_data_context(
6044 server_.get(), server_quic_early_data_context_.data(),
6045 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07006046 return false;
6047 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006048 return true;
6049 }
6050
Nick Harper72cff812020-03-26 18:06:16 -07006051 enum class ExpectedError {
6052 kNoError,
6053 kClientError,
6054 kServerError,
6055 };
6056
David Benjamind6343572019-08-15 17:29:02 -04006057 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
6058 // |server_| until each completes once. It returns true on success and false
6059 // on failure.
6060 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07006061 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
6062 }
6063
6064 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
6065 // once. If |expect_client_error| is true, it will return true only if the
6066 // client handshake failed. Otherwise, it returns true if both handshakes
6067 // succeed and false otherwise.
6068 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04006069 bool client_done = false, server_done = false;
6070 while (!client_done || !server_done) {
6071 if (!client_done) {
6072 if (!ProvideHandshakeData(client_.get())) {
6073 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
6074 return false;
6075 }
6076 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006077 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04006078 if (client_ret == 1) {
6079 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006080 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006081 if (expected_error == ExpectedError::kClientError) {
6082 return true;
6083 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006084 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
6085 << client_err;
6086 return false;
David Benjamind6343572019-08-15 17:29:02 -04006087 }
6088 }
6089
6090 if (!server_done) {
6091 if (!ProvideHandshakeData(server_.get())) {
6092 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
6093 return false;
6094 }
6095 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006096 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04006097 if (server_ret == 1) {
6098 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006099 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006100 if (expected_error == ExpectedError::kServerError) {
6101 return true;
6102 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006103 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
6104 << server_err;
6105 return false;
David Benjamind6343572019-08-15 17:29:02 -04006106 }
6107 }
6108 }
Nick Harper72cff812020-03-26 18:06:16 -07006109 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04006110 }
6111
6112 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
6113 g_last_session = nullptr;
6114 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6115 if (!CreateClientAndServer() ||
6116 !CompleteHandshakesForQUIC()) {
6117 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006118 }
6119
David Benjamind6343572019-08-15 17:29:02 -04006120 // The server sent NewSessionTicket messages in the handshake.
6121 if (!ProvideHandshakeData(client_.get()) ||
6122 !SSL_process_quic_post_handshake(client_.get())) {
6123 return nullptr;
6124 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006125
David Benjamind6343572019-08-15 17:29:02 -04006126 return std::move(g_last_session);
6127 }
6128
6129 void ExpectHandshakeSuccess() {
6130 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6131 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
6132 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
6133 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
6134 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
6135 EXPECT_FALSE(transport_->client()->has_alert());
6136 EXPECT_FALSE(transport_->server()->has_alert());
6137
6138 // SSL_do_handshake is now idempotent.
6139 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6140 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006141 }
6142
David Benjamin1e859052020-02-09 16:04:58 -05006143 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
6144 // the test.
6145 SSL_QUIC_METHOD DefaultQUICMethod() {
6146 return SSL_QUIC_METHOD{
6147 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
6148 FlushFlightCallback, SendAlertCallback,
6149 };
6150 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006151
David Benjamin1e859052020-02-09 16:04:58 -05006152 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6153 const SSL_CIPHER *cipher,
6154 const uint8_t *secret, size_t secret_len) {
6155 return TransportFromSSL(ssl)->SetReadSecret(
6156 level, cipher, MakeConstSpan(secret, secret_len));
6157 }
6158
6159 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6160 const SSL_CIPHER *cipher,
6161 const uint8_t *secret, size_t secret_len) {
6162 return TransportFromSSL(ssl)->SetWriteSecret(
6163 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006164 }
6165
David Benjamincc9d9352018-10-30 19:45:22 -05006166 static int AddHandshakeDataCallback(SSL *ssl,
6167 enum ssl_encryption_level_t level,
6168 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006169 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6170 return TransportFromSSL(ssl)->WriteHandshakeData(level,
6171 MakeConstSpan(data, len));
6172 }
6173
6174 static int FlushFlightCallback(SSL *ssl) { return 1; }
6175
6176 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6177 uint8_t alert) {
6178 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6179 return TransportFromSSL(ssl)->SendAlert(level, alert);
6180 }
6181
6182 bssl::UniquePtr<SSL_CTX> client_ctx_;
6183 bssl::UniquePtr<SSL_CTX> server_ctx_;
6184
6185 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04006186 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006187
6188 bssl::UniquePtr<SSL> client_;
6189 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04006190
Nick Harper7c522992020-04-30 14:15:49 -07006191 std::vector<uint8_t> server_transport_params_ = {1};
6192 std::vector<uint8_t> server_quic_early_data_context_ = {2};
6193
David Benjamin5298ef92020-03-13 12:17:30 -04006194 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006195};
6196
6197UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6198
David Benjaminfd863b62019-07-25 13:51:32 -04006199// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006200TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05006201 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006202
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006203 g_last_session = nullptr;
6204
6205 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6206 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006207 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6208 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04006209
Steven Valdezc8e0f902018-07-14 11:23:01 -04006210 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006211 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006212
David Benjamind6343572019-08-15 17:29:02 -04006213 ExpectHandshakeSuccess();
6214 EXPECT_FALSE(SSL_session_reused(client_.get()));
6215 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006216
6217 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006218 EXPECT_FALSE(g_last_session);
6219 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6220 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6221 EXPECT_TRUE(g_last_session);
6222
6223 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04006224 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006225 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6226 SSL_set_session(client_.get(), session.get());
6227
David Benjamind6343572019-08-15 17:29:02 -04006228 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006229
David Benjamind6343572019-08-15 17:29:02 -04006230 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006231 EXPECT_TRUE(SSL_session_reused(client_.get()));
6232 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006233}
6234
David Benjaminfd863b62019-07-25 13:51:32 -04006235// Test that HelloRetryRequest in QUIC works.
6236TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006237 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006238
6239 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6240 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6241
6242 // BoringSSL predicts the most preferred curve, so using different preferences
6243 // will trigger HelloRetryRequest.
6244 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6245 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
6246 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6247 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6248 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
6249 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6250
6251 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006252 ASSERT_TRUE(CompleteHandshakesForQUIC());
6253 ExpectHandshakeSuccess();
6254}
David Benjaminfd863b62019-07-25 13:51:32 -04006255
Nick Harpere32549e2020-05-06 14:27:11 -07006256// Test that the client does not send a legacy_session_id in the ClientHello.
6257TEST_F(QUICMethodTest, NoLegacySessionId) {
6258 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6259
6260 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6261 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6262 // Check that the session ID length is 0 in an early callback.
6263 SSL_CTX_set_select_certificate_cb(
6264 server_ctx_.get(),
6265 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6266 EXPECT_EQ(client_hello->session_id_len, 0u);
6267 return ssl_select_cert_success;
6268 });
6269
6270 ASSERT_TRUE(CreateClientAndServer());
6271 ASSERT_TRUE(CompleteHandshakesForQUIC());
6272
6273 ExpectHandshakeSuccess();
6274}
6275
David Benjamin1e859052020-02-09 16:04:58 -05006276// Test that, even in a 1-RTT handshake, the server installs keys at the right
6277// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6278TEST_F(QUICMethodTest, HalfRTTKeys) {
6279 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6280
6281 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6282 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6283 ASSERT_TRUE(CreateClientAndServer());
6284
6285 // The client sends ClientHello.
6286 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6287 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6288
6289 // The server reads ClientHello and sends ServerHello..Finished.
6290 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6291 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6292 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6293
6294 // At this point, the server has half-RTT write keys, but it cannot access
6295 // 1-RTT read keys until client Finished.
6296 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6297 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6298
6299 // Finish up the client and server handshakes.
6300 ASSERT_TRUE(CompleteHandshakesForQUIC());
6301
6302 // Both sides can now exchange 1-RTT data.
6303 ExpectHandshakeSuccess();
6304}
6305
David Benjamind6343572019-08-15 17:29:02 -04006306TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006307 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006308
6309 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6310 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6311 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6312 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6313 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6314
6315 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6316 ASSERT_TRUE(session);
6317
6318 ASSERT_TRUE(CreateClientAndServer());
6319 SSL_set_session(client_.get(), session.get());
6320
6321 // The client handshake should return immediately into the early data state.
6322 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6323 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6324 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006325 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006326
6327 // The server will consume the ClientHello and also enter the early data
6328 // state.
6329 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6330 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6331 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6332 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006333 // At this point, the server has half-RTT write keys, but it cannot access
6334 // 1-RTT read keys until client Finished.
6335 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6336 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006337
6338 // Finish up the client and server handshakes.
6339 ASSERT_TRUE(CompleteHandshakesForQUIC());
6340
6341 // Both sides can now exchange 1-RTT data.
6342 ExpectHandshakeSuccess();
6343 EXPECT_TRUE(SSL_session_reused(client_.get()));
6344 EXPECT_TRUE(SSL_session_reused(server_.get()));
6345 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6346 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6347 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6348 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006349
6350 // Finish handling post-handshake messages after the first 0-RTT resumption.
6351 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6352 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6353
6354 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6355 // accepted again.
6356 ASSERT_TRUE(CreateClientAndServer());
6357 SSL_set_session(client_.get(), g_last_session.get());
6358
6359 // The client handshake should return immediately into the early data state.
6360 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6361 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6362 // The transport should have keys for sending 0-RTT data.
6363 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6364
6365 // The server will consume the ClientHello and also enter the early data
6366 // state.
6367 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6368 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6369 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6370 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6371 // At this point, the server has half-RTT write keys, but it cannot access
6372 // 1-RTT read keys until client Finished.
6373 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6374 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6375
6376 // Finish up the client and server handshakes.
6377 ASSERT_TRUE(CompleteHandshakesForQUIC());
6378
6379 // Both sides can now exchange 1-RTT data.
6380 ExpectHandshakeSuccess();
6381 EXPECT_TRUE(SSL_session_reused(client_.get()));
6382 EXPECT_TRUE(SSL_session_reused(server_.get()));
6383 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6384 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6385 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6386 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6387 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6388 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006389}
6390
Nick Harper7c522992020-04-30 14:15:49 -07006391TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6392 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6393
6394 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6395 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6396 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6397 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6398 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6399
6400
6401 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6402 ASSERT_TRUE(session);
6403
Nick Harper85194322020-05-20 16:59:29 -07006404 ASSERT_TRUE(CreateClientAndServer());
6405 static const uint8_t new_context[] = {4};
6406 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6407 sizeof(new_context)));
6408 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006409
Nick Harper85194322020-05-20 16:59:29 -07006410 // The client handshake should return immediately into the early data
6411 // state.
6412 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6413 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6414 // The transport should have keys for sending 0-RTT data.
6415 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006416
Nick Harper85194322020-05-20 16:59:29 -07006417 // The server will consume the ClientHello, but it will not accept 0-RTT.
6418 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6419 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6420 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6421 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6422 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006423
Nick Harper85194322020-05-20 16:59:29 -07006424 // The client consumes the server response and signals 0-RTT rejection.
6425 for (;;) {
6426 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6427 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6428 int err = SSL_get_error(client_.get(), -1);
6429 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6430 break;
Nick Harper7c522992020-04-30 14:15:49 -07006431 }
Nick Harper85194322020-05-20 16:59:29 -07006432 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006433 }
Nick Harper85194322020-05-20 16:59:29 -07006434
6435 // As in TLS over TCP, 0-RTT rejection is sticky.
6436 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6437 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6438
6439 // Finish up the client and server handshakes.
6440 SSL_reset_early_data_reject(client_.get());
6441 ASSERT_TRUE(CompleteHandshakesForQUIC());
6442
6443 // Both sides can now exchange 1-RTT data.
6444 ExpectHandshakeSuccess();
6445 EXPECT_TRUE(SSL_session_reused(client_.get()));
6446 EXPECT_TRUE(SSL_session_reused(server_.get()));
6447 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6448 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6449 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6450 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6451}
6452
6453TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6454 server_quic_early_data_context_ = {};
6455 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6456
6457 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6458 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6459 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6460 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6461 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6462
6463 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6464 ASSERT_TRUE(session);
6465 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006466}
6467
David Benjamind6343572019-08-15 17:29:02 -04006468TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006469 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006470
6471 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6472 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6473 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6474 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6475 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6476
6477 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6478 ASSERT_TRUE(session);
6479
6480 for (bool reject_hrr : {false, true}) {
6481 SCOPED_TRACE(reject_hrr);
6482
6483 ASSERT_TRUE(CreateClientAndServer());
6484 if (reject_hrr) {
6485 // Configure the server to prefer P-256, which will reject 0-RTT via
6486 // HelloRetryRequest.
6487 int p256 = NID_X9_62_prime256v1;
6488 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6489 } else {
6490 // Disable 0-RTT on the server, so it will reject it.
6491 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006492 }
David Benjamind6343572019-08-15 17:29:02 -04006493 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006494
David Benjamind6343572019-08-15 17:29:02 -04006495 // The client handshake should return immediately into the early data state.
6496 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6497 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6498 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006499 EXPECT_TRUE(
6500 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006501
6502 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006503 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006504 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6505 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6506 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006507 EXPECT_FALSE(
6508 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006509
6510 // The client consumes the server response and signals 0-RTT rejection.
6511 for (;;) {
6512 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6513 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6514 int err = SSL_get_error(client_.get(), -1);
6515 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6516 break;
6517 }
6518 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006519 }
6520
David Benjamind6343572019-08-15 17:29:02 -04006521 // As in TLS over TCP, 0-RTT rejection is sticky.
6522 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6523 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6524
6525 // Finish up the client and server handshakes.
6526 SSL_reset_early_data_reject(client_.get());
6527 ASSERT_TRUE(CompleteHandshakesForQUIC());
6528
6529 // Both sides can now exchange 1-RTT data.
6530 ExpectHandshakeSuccess();
6531 EXPECT_TRUE(SSL_session_reused(client_.get()));
6532 EXPECT_TRUE(SSL_session_reused(server_.get()));
6533 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6534 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6535 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6536 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006537 }
David Benjaminfd863b62019-07-25 13:51:32 -04006538}
6539
David Benjaminee0716f2019-11-19 14:16:28 +08006540TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006541 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006542
6543 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6544 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6545 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6546 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6547 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6548 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6549
6550 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6551 ASSERT_TRUE(session);
6552
6553 ASSERT_TRUE(CreateClientAndServer());
6554 SSL_set_session(client_.get(), session.get());
6555
6556 // Configure the certificate (re)verification to never complete. The client
6557 // handshake should pause.
6558 SSL_set_custom_verify(
6559 client_.get(), SSL_VERIFY_PEER,
6560 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6561 return ssl_verify_retry;
6562 });
6563 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6564 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6565 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6566
6567 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006568 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006569
6570 // After the verification completes, the handshake progresses to the 0-RTT
6571 // point and releases keys.
6572 SSL_set_custom_verify(
6573 client_.get(), SSL_VERIFY_PEER,
6574 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6575 return ssl_verify_ok;
6576 });
6577 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6578 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006579 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006580}
6581
Steven Valdezc8e0f902018-07-14 11:23:01 -04006582// Test only releasing data to QUIC one byte at a time on request, to maximize
6583// state machine pauses. Additionally, test that existing asynchronous callbacks
6584// still work.
6585TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006586 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006587
6588 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6589 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6590 ASSERT_TRUE(CreateClientAndServer());
6591
6592 // Install an asynchronous certificate callback.
6593 bool cert_cb_ok = false;
6594 SSL_set_cert_cb(server_.get(),
6595 [](SSL *, void *arg) -> int {
6596 return *static_cast<bool *>(arg) ? 1 : -1;
6597 },
6598 &cert_cb_ok);
6599
6600 for (;;) {
6601 int client_ret = SSL_do_handshake(client_.get());
6602 if (client_ret != 1) {
6603 ASSERT_EQ(client_ret, -1);
6604 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6605 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6606 }
6607
6608 int server_ret = SSL_do_handshake(server_.get());
6609 if (server_ret != 1) {
6610 ASSERT_EQ(server_ret, -1);
6611 int ssl_err = SSL_get_error(server_.get(), server_ret);
6612 switch (ssl_err) {
6613 case SSL_ERROR_WANT_READ:
6614 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6615 break;
6616 case SSL_ERROR_WANT_X509_LOOKUP:
6617 ASSERT_FALSE(cert_cb_ok);
6618 cert_cb_ok = true;
6619 break;
6620 default:
6621 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6622 }
6623 }
6624
6625 if (client_ret == 1 && server_ret == 1) {
6626 break;
6627 }
6628 }
6629
David Benjamind6343572019-08-15 17:29:02 -04006630 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006631}
6632
6633// Test buffering write data until explicit flushes.
6634TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006635 AllowOutOfOrderWrites();
6636
Steven Valdezc8e0f902018-07-14 11:23:01 -04006637 struct BufferedFlight {
6638 std::vector<uint8_t> data[kNumQUICLevels];
6639 };
6640 static UnownedSSLExData<BufferedFlight> buffered_flights;
6641
David Benjamincc9d9352018-10-30 19:45:22 -05006642 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6643 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006644 BufferedFlight *flight = buffered_flights.Get(ssl);
6645 flight->data[level].insert(flight->data[level].end(), data, data + len);
6646 return 1;
6647 };
6648
6649 auto flush_flight = [](SSL *ssl) -> int {
6650 BufferedFlight *flight = buffered_flights.Get(ssl);
6651 for (size_t level = 0; level < kNumQUICLevels; level++) {
6652 if (!flight->data[level].empty()) {
6653 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6654 static_cast<ssl_encryption_level_t>(level),
6655 flight->data[level])) {
6656 return 0;
6657 }
6658 flight->data[level].clear();
6659 }
6660 }
6661 return 1;
6662 };
6663
David Benjamin1e859052020-02-09 16:04:58 -05006664 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6665 quic_method.add_handshake_data = add_handshake_data;
6666 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006667
6668 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6669 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6670 ASSERT_TRUE(CreateClientAndServer());
6671
6672 BufferedFlight client_flight, server_flight;
6673 buffered_flights.Set(client_.get(), &client_flight);
6674 buffered_flights.Set(server_.get(), &server_flight);
6675
David Benjamind6343572019-08-15 17:29:02 -04006676 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006677
David Benjamind6343572019-08-15 17:29:02 -04006678 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006679}
6680
6681// Test that excess data at one level is rejected. That is, if a single
6682// |SSL_provide_quic_data| call included both ServerHello and
6683// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6684// key change.
6685TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006686 AllowOutOfOrderWrites();
6687
David Benjamincc9d9352018-10-30 19:45:22 -05006688 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6689 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006690 // Switch everything to the initial level.
6691 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6692 MakeConstSpan(data, len));
6693 };
6694
David Benjamin1e859052020-02-09 16:04:58 -05006695 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6696 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006697
6698 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6699 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6700 ASSERT_TRUE(CreateClientAndServer());
6701
6702 // Send the ClientHello and ServerHello through Finished.
6703 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6704 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6705 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6706 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6707 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6708
6709 // The client is still waiting for the ServerHello at initial
6710 // encryption.
6711 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6712
David Benjamincc9d9352018-10-30 19:45:22 -05006713 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6714 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006715 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6716
6717 // The client reads ServerHello successfully, but then rejects the buffered
6718 // EncryptedExtensions on key change.
6719 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6720 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6721 uint32_t err = ERR_get_error();
6722 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006723 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006724
David Benjamin1e859052020-02-09 16:04:58 -05006725 // The client sends an alert in response to this. The alert is sent at
6726 // handshake level because we install write secrets before read secrets and
6727 // the error is discovered when installing the read secret. (How to send
6728 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006729 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006730 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006731 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006732
David Benjamin5298ef92020-03-13 12:17:30 -04006733 // Sanity-check handshake secrets. The error is discovered while setting the
6734 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006735 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006736 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006737}
6738
6739// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6740TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006741 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006742
6743 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6744 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6745 ASSERT_TRUE(CreateClientAndServer());
6746
6747 // Send the ClientHello and ServerHello through Finished.
6748 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6749 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6750 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6751 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6752 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6753
6754 // The client is still waiting for the ServerHello at initial
6755 // encryption.
6756 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6757
6758 // Data cannot be provided at the next level.
6759 std::vector<uint8_t> data;
6760 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006761 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006762 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6763 data.data(), data.size()));
6764 ERR_clear_error();
6765
6766 // Progress to EncryptedExtensions.
6767 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6768 data.data(), data.size()));
6769 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6770 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6771 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6772
6773 // Data cannot be provided at the previous level.
6774 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006775 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006776 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6777 data.data(), data.size()));
6778}
6779
6780TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006781 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006782
6783 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6784 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6785 ASSERT_TRUE(CreateClientAndServer());
6786
6787 size_t limit =
6788 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6789 uint8_t b = 0;
6790 for (size_t i = 0; i < limit; i++) {
6791 ASSERT_TRUE(
6792 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6793 }
6794
6795 EXPECT_FALSE(
6796 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6797}
6798
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006799// Provide invalid post-handshake data.
6800TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006801 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006802
6803 g_last_session = nullptr;
6804
6805 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6806 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6807 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6808 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6809 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006810 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006811
6812 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6813 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006814 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6815 EXPECT_FALSE(transport_->client()->has_alert());
6816 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006817
6818 // Junk sent as part of post-handshake data should cause an error.
6819 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6820 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6821 kJunk, sizeof(kJunk)));
6822 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6823}
6824
Nick Harper80ddfc72020-03-11 18:26:31 -07006825static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6826 Span<const uint8_t> expected) {
6827 const uint8_t *received;
6828 size_t received_len;
6829 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6830 ASSERT_EQ(received_len, expected.size());
6831 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6832}
6833
6834TEST_F(QUICMethodTest, SetTransportParameters) {
6835 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6836 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6837 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6838
6839 ASSERT_TRUE(CreateClientAndServer());
6840 uint8_t kClientParams[] = {1, 2, 3, 4};
6841 uint8_t kServerParams[] = {5, 6, 7};
6842 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6843 sizeof(kClientParams)));
6844 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6845 sizeof(kServerParams)));
6846
6847 ASSERT_TRUE(CompleteHandshakesForQUIC());
6848 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6849 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6850}
6851
6852TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6853 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6854 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6855 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6856
6857 ASSERT_TRUE(CreateClientAndServer());
6858 uint8_t kClientParams[] = {1, 2, 3, 4};
6859 static uint8_t kServerParams[] = {5, 6, 7};
6860 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6861 sizeof(kClientParams)));
6862 SSL_CTX_set_tlsext_servername_callback(
6863 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6864 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6865 sizeof(kServerParams)));
6866 return SSL_TLSEXT_ERR_OK;
6867 });
6868
6869 ASSERT_TRUE(CompleteHandshakesForQUIC());
6870 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6871 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6872}
6873
Nick Harper6bfd25c2020-03-30 17:15:19 -07006874TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6875 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6876
6877 g_last_session = nullptr;
6878
6879 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6880 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6881 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6882 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6883
6884 ASSERT_TRUE(CreateClientAndServer());
6885 ASSERT_TRUE(CompleteHandshakesForQUIC());
6886
6887 ExpectHandshakeSuccess();
6888 EXPECT_FALSE(SSL_session_reused(client_.get()));
6889 EXPECT_FALSE(SSL_session_reused(server_.get()));
6890
6891 // The server sent NewSessionTicket messages in the handshake.
6892 EXPECT_FALSE(g_last_session);
6893 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6894 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6895 EXPECT_TRUE(g_last_session);
6896
6897 // Pretend that g_last_session came from a TLS-over-TCP connection.
6898 g_last_session.get()->is_quic = false;
6899
6900 // Create a second connection and verify that resumption does not occur with
6901 // a session from a non-QUIC connection. This tests that the client does not
6902 // offer over QUIC a session believed to be received over TCP. The server
6903 // believes this is a QUIC session, so if the client offered the session, the
6904 // server would have resumed it.
6905 ASSERT_TRUE(CreateClientAndServer());
6906 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6907 SSL_set_session(client_.get(), session.get());
6908
6909 ASSERT_TRUE(CompleteHandshakesForQUIC());
6910 ExpectHandshakeSuccess();
6911 EXPECT_FALSE(SSL_session_reused(client_.get()));
6912 EXPECT_FALSE(SSL_session_reused(server_.get()));
6913}
6914
6915TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6916 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6917
6918 g_last_session = nullptr;
6919
6920 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6921 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6922 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6923 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6924
6925 ASSERT_TRUE(CreateClientAndServer());
6926 ASSERT_TRUE(CompleteHandshakesForQUIC());
6927
6928 ExpectHandshakeSuccess();
6929 EXPECT_FALSE(SSL_session_reused(client_.get()));
6930 EXPECT_FALSE(SSL_session_reused(server_.get()));
6931
6932 // The server sent NewSessionTicket messages in the handshake.
6933 EXPECT_FALSE(g_last_session);
6934 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6935 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6936 EXPECT_TRUE(g_last_session);
6937
6938 // Attempt a resumption with g_last_session using TLS_method.
6939 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6940 ASSERT_TRUE(client_ctx);
6941
6942 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6943
6944 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6945 server(SSL_new(server_ctx_.get()));
6946 ASSERT_TRUE(client);
6947 ASSERT_TRUE(server);
6948 SSL_set_connect_state(client.get());
6949 SSL_set_accept_state(server.get());
6950
6951 // The TLS-over-TCP client will refuse to resume with a quic session, so
6952 // mark is_quic = false to bypass the client check to test the server check.
6953 g_last_session.get()->is_quic = false;
6954 SSL_set_session(client.get(), g_last_session.get());
6955
6956 BIO *bio1, *bio2;
6957 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6958
6959 // SSL_set_bio takes ownership.
6960 SSL_set_bio(client.get(), bio1, bio1);
6961 SSL_set_bio(server.get(), bio2, bio2);
6962 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6963
6964 EXPECT_FALSE(SSL_session_reused(client.get()));
6965 EXPECT_FALSE(SSL_session_reused(server.get()));
6966}
6967
Nick Harper72cff812020-03-26 18:06:16 -07006968TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6969 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6970 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6971 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6972
6973 ASSERT_TRUE(CreateClientAndServer());
6974 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6975 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6976}
6977
6978TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6979 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6980 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6981 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6982
6983 ASSERT_TRUE(CreateClientAndServer());
6984 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6985 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6986}
6987
David Schinazi3d8b8c32021-01-14 11:25:49 -08006988TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6989 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6990 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6991 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6992
6993 ASSERT_TRUE(CreateClientAndServer());
6994 uint8_t kClientParams[] = {1, 2, 3, 4};
6995 uint8_t kServerParams[] = {5, 6, 7};
6996 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6997 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6998 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6999 sizeof(kClientParams)));
7000 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7001 sizeof(kServerParams)));
7002
7003 ASSERT_TRUE(CompleteHandshakesForQUIC());
7004 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7005 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7006}
7007
7008TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
7009 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7010 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7011 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7012
7013 ASSERT_TRUE(CreateClientAndServer());
7014 uint8_t kClientParams[] = {1, 2, 3, 4};
7015 uint8_t kServerParams[] = {5, 6, 7};
7016 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7017 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7018 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7019 sizeof(kClientParams)));
7020 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7021 sizeof(kServerParams)));
7022
7023 ASSERT_TRUE(CompleteHandshakesForQUIC());
7024 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7025 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7026}
7027
7028TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
7029 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7030 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7031 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7032
7033 ASSERT_TRUE(CreateClientAndServer());
7034 uint8_t kClientParams[] = {1, 2, 3, 4};
7035 uint8_t kServerParams[] = {5, 6, 7};
7036 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7037 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7038 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7039 sizeof(kClientParams)));
7040 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7041 sizeof(kServerParams)));
7042
7043 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7044}
7045
7046TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
7047 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7048 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7049 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7050
7051 ASSERT_TRUE(CreateClientAndServer());
7052 uint8_t kClientParams[] = {1, 2, 3, 4};
7053 uint8_t kServerParams[] = {5, 6, 7};
7054 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7055 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7056 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7057 sizeof(kClientParams)));
7058 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7059 sizeof(kServerParams)));
7060
7061 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7062}
7063
David Benjaminc47bfce2021-01-20 17:10:32 -05007064// Test that the default QUIC code point is consistent with
7065// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
7066// update the two values together.
7067TEST_F(QUICMethodTest, QuicCodePointDefault) {
7068 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7069 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7070 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7071 SSL_CTX_set_select_certificate_cb(
7072 server_ctx_.get(),
7073 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7074 const uint8_t *data;
7075 size_t len;
7076 if (!SSL_early_callback_ctx_extension_get(
7077 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
7078 &len)) {
7079 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
7080 return ssl_select_cert_error;
7081 }
7082 return ssl_select_cert_success;
7083 });
7084
7085 ASSERT_TRUE(CreateClientAndServer());
7086 ASSERT_TRUE(CompleteHandshakesForQUIC());
7087}
7088
Adam Langley7540cc22019-04-18 09:56:13 -07007089extern "C" {
7090int BORINGSSL_enum_c_type_test(void);
7091}
7092
7093TEST(SSLTest, EnumTypes) {
7094 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
7095 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
7096}
7097
David Benjaminb29e1e12019-05-06 14:44:46 -05007098TEST_P(SSLVersionTest, DoubleSSLError) {
7099 // Connect the inner SSL connections.
7100 ASSERT_TRUE(Connect());
7101
7102 // Make a pair of |BIO|s which wrap |client_| and |server_|.
7103 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
7104 ASSERT_TRUE(bio_method);
7105 ASSERT_TRUE(BIO_meth_set_read(
7106 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
7107 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7108 int ret = SSL_read(ssl, out, len);
7109 int ssl_ret = SSL_get_error(ssl, ret);
7110 if (ssl_ret == SSL_ERROR_WANT_READ) {
7111 BIO_set_retry_read(bio);
7112 }
7113 return ret;
7114 }));
7115 ASSERT_TRUE(BIO_meth_set_write(
7116 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
7117 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7118 int ret = SSL_write(ssl, in, len);
7119 int ssl_ret = SSL_get_error(ssl, ret);
7120 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
7121 BIO_set_retry_write(bio);
7122 }
7123 return ret;
7124 }));
7125 ASSERT_TRUE(BIO_meth_set_ctrl(
7126 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
7127 // |SSL| objects require |BIO_flush| support.
7128 if (cmd == BIO_CTRL_FLUSH) {
7129 return 1;
7130 }
7131 return 0;
7132 }));
7133
7134 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
7135 ASSERT_TRUE(client_bio);
7136 BIO_set_data(client_bio.get(), client_.get());
7137 BIO_set_init(client_bio.get(), 1);
7138
7139 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
7140 ASSERT_TRUE(server_bio);
7141 BIO_set_data(server_bio.get(), server_.get());
7142 BIO_set_init(server_bio.get(), 1);
7143
7144 // Wrap the inner connections in another layer of SSL.
7145 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
7146 ASSERT_TRUE(client_outer);
7147 SSL_set_connect_state(client_outer.get());
7148 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
7149 client_bio.release(); // |SSL_set_bio| takes ownership.
7150
7151 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7152 ASSERT_TRUE(server_outer);
7153 SSL_set_accept_state(server_outer.get());
7154 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7155 server_bio.release(); // |SSL_set_bio| takes ownership.
7156
7157 // Configure |client_outer| to reject the server certificate.
7158 SSL_set_custom_verify(
7159 client_outer.get(), SSL_VERIFY_PEER,
7160 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7161 return ssl_verify_invalid;
7162 });
7163
7164 for (;;) {
7165 int client_ret = SSL_do_handshake(client_outer.get());
7166 int client_err = SSL_get_error(client_outer.get(), client_ret);
7167 if (client_err != SSL_ERROR_WANT_READ &&
7168 client_err != SSL_ERROR_WANT_WRITE) {
7169 // The client handshake should terminate on a certificate verification
7170 // error.
7171 EXPECT_EQ(SSL_ERROR_SSL, client_err);
7172 uint32_t err = ERR_peek_error();
7173 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7174 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
7175 break;
7176 }
7177
7178 // Run the server handshake and continue.
7179 int server_ret = SSL_do_handshake(server_outer.get());
7180 int server_err = SSL_get_error(server_outer.get(), server_ret);
7181 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7182 server_err == SSL_ERROR_WANT_READ ||
7183 server_err == SSL_ERROR_WANT_WRITE);
7184 }
7185}
7186
David Benjamin1b819472020-06-09 14:01:02 -04007187TEST_P(SSLVersionTest, SameKeyResume) {
7188 uint8_t key[48];
7189 RAND_bytes(key, sizeof(key));
7190
7191 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7192 ASSERT_TRUE(server_ctx2);
7193 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7194 ASSERT_TRUE(
7195 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7196 ASSERT_TRUE(
7197 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7198
7199 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7200 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7201 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7202
7203 // Establish a session for |server_ctx_|.
7204 bssl::UniquePtr<SSL_SESSION> session =
7205 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7206 ASSERT_TRUE(session);
7207 ClientConfig config;
7208 config.session = session.get();
7209
7210 // Resuming with |server_ctx_| again works.
7211 bssl::UniquePtr<SSL> client, server;
7212 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7213 server_ctx_.get(), config));
7214 EXPECT_TRUE(SSL_session_reused(client.get()));
7215 EXPECT_TRUE(SSL_session_reused(server.get()));
7216
7217 // Resuming with |server_ctx2| also works.
7218 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7219 server_ctx2.get(), config));
7220 EXPECT_TRUE(SSL_session_reused(client.get()));
7221 EXPECT_TRUE(SSL_session_reused(server.get()));
7222}
7223
7224TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7225 uint8_t key1[48], key2[48];
7226 RAND_bytes(key1, sizeof(key1));
7227 RAND_bytes(key2, sizeof(key2));
7228
7229 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7230 ASSERT_TRUE(server_ctx2);
7231 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7232 ASSERT_TRUE(
7233 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7234 ASSERT_TRUE(
7235 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7236
7237 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7238 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7239 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7240
7241 // Establish a session for |server_ctx_|.
7242 bssl::UniquePtr<SSL_SESSION> session =
7243 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7244 ASSERT_TRUE(session);
7245 ClientConfig config;
7246 config.session = session.get();
7247
7248 // Resuming with |server_ctx_| again works.
7249 bssl::UniquePtr<SSL> client, server;
7250 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7251 server_ctx_.get(), config));
7252 EXPECT_TRUE(SSL_session_reused(client.get()));
7253 EXPECT_TRUE(SSL_session_reused(server.get()));
7254
7255 // Resuming with |server_ctx2| does not work.
7256 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7257 server_ctx2.get(), config));
7258 EXPECT_FALSE(SSL_session_reused(client.get()));
7259 EXPECT_FALSE(SSL_session_reused(server.get()));
7260}
7261
7262TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7263 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7264 ASSERT_TRUE(server_ctx2);
7265 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7266
7267 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7268 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7269 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7270
7271 // Establish a session for |server_ctx_|.
7272 bssl::UniquePtr<SSL_SESSION> session =
7273 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7274 ASSERT_TRUE(session);
7275 ClientConfig config;
7276 config.session = session.get();
7277
7278 // Resuming with |server_ctx_| again works.
7279 bssl::UniquePtr<SSL> client, server;
7280 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7281 server_ctx_.get(), config));
7282 EXPECT_TRUE(SSL_session_reused(client.get()));
7283 EXPECT_TRUE(SSL_session_reused(server.get()));
7284
7285 // Resuming with |server_ctx2| does not work.
7286 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7287 server_ctx2.get(), config));
7288 EXPECT_FALSE(SSL_session_reused(client.get()));
7289 EXPECT_FALSE(SSL_session_reused(server.get()));
7290}
7291
Adam Langley47cefed2021-05-26 13:36:40 -07007292Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7293 const SSL_SESSION *session = SSL_get_session(ssl);
7294 unsigned len;
7295 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7296 return MakeConstSpan(data, len);
7297}
7298
7299TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7300 // This checks that the session IDs at client and server match after a ticket
7301 // resumption. It's unclear whether this should be true, but Envoy depends
7302 // on it in their tests so this will give an early signal if we break it.
7303 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7304 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7305
7306 bssl::UniquePtr<SSL_SESSION> session =
7307 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7308
7309 bssl::UniquePtr<SSL> client, server;
7310 ClientConfig config;
7311 config.session = session.get();
7312 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7313 server_ctx_.get(), config));
7314 EXPECT_TRUE(SSL_session_reused(client.get()));
7315 EXPECT_TRUE(SSL_session_reused(server.get()));
7316
7317 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7318}
7319
David Benjamin10fef972022-08-30 11:38:51 -04007320static void WriteHelloRequest(SSL *server) {
7321 // This function assumes TLS 1.2 with ChaCha20-Poly1305.
7322 ASSERT_EQ(SSL_version(server), TLS1_2_VERSION);
7323 ASSERT_EQ(SSL_CIPHER_get_cipher_nid(SSL_get_current_cipher(server)),
7324 NID_chacha20_poly1305);
David Benjamin0e7dbd52019-05-15 16:01:18 -04007325
7326 // Encrypt a HelloRequest.
7327 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7328#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7329 // Fuzzer-mode records are unencrypted.
7330 uint8_t record[5 + sizeof(in)];
7331 record[0] = SSL3_RT_HANDSHAKE;
7332 record[1] = 3;
7333 record[2] = 3; // TLS 1.2
7334 record[3] = 0;
7335 record[4] = sizeof(record) - 5;
7336 memcpy(record + 5, in, sizeof(in));
7337#else
7338 // Extract key material from |server|.
7339 static const size_t kKeyLen = 32;
7340 static const size_t kNonceLen = 12;
David Benjamin10fef972022-08-30 11:38:51 -04007341 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007342 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
David Benjamin10fef972022-08-30 11:38:51 -04007343 ASSERT_TRUE(SSL_generate_key_block(server, key_block, sizeof(key_block)));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007344 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7345 Span<uint8_t> nonce =
7346 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7347
7348 uint8_t ad[13];
David Benjamin10fef972022-08-30 11:38:51 -04007349 uint64_t seq = SSL_get_write_sequence(server);
David Benjamin0e7dbd52019-05-15 16:01:18 -04007350 for (size_t i = 0; i < 8; i++) {
7351 // The nonce is XORed with the sequence number.
7352 nonce[11 - i] ^= uint8_t(seq);
7353 ad[7 - i] = uint8_t(seq);
7354 seq >>= 8;
7355 }
7356
7357 ad[8] = SSL3_RT_HANDSHAKE;
7358 ad[9] = 3;
7359 ad[10] = 3; // TLS 1.2
7360 ad[11] = 0;
7361 ad[12] = sizeof(in);
7362
7363 uint8_t record[5 + sizeof(in) + 16];
7364 record[0] = SSL3_RT_HANDSHAKE;
7365 record[1] = 3;
7366 record[2] = 3; // TLS 1.2
7367 record[3] = 0;
7368 record[4] = sizeof(record) - 5;
7369
7370 ScopedEVP_AEAD_CTX aead;
7371 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7372 key.data(), key.size(),
7373 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7374 size_t len;
7375 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7376 sizeof(record) - 5, nonce.data(), nonce.size(),
7377 in, sizeof(in), ad, sizeof(ad)));
7378 ASSERT_EQ(sizeof(record) - 5, len);
7379#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7380
7381 ASSERT_EQ(int(sizeof(record)),
David Benjamin10fef972022-08-30 11:38:51 -04007382 BIO_write(SSL_get_wbio(server), record, sizeof(record)));
7383}
7384
7385TEST(SSLTest, WriteWhileExplicitRenegotiate) {
7386 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
7387 ASSERT_TRUE(ctx);
7388
7389 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7390 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7391 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7392 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7393
7394 bssl::UniquePtr<SSL> client, server;
7395 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
7396 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
7397 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7398
7399 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7400
7401 // Write "hello" until the buffer is full, so |client| has a pending write.
7402 size_t num_writes = 0;
7403 for (;;) {
7404 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7405 if (ret != int(sizeof(kInput))) {
7406 ASSERT_EQ(-1, ret);
7407 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7408 break;
7409 }
7410 num_writes++;
7411 }
7412
7413 ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007414
7415 // |SSL_read| should pick up the HelloRequest.
7416 uint8_t byte;
7417 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7418 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7419
7420 // Drain the data from the |client|.
7421 uint8_t buf[sizeof(kInput)];
7422 for (size_t i = 0; i < num_writes; i++) {
7423 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7424 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7425 }
7426
7427 // |client| should be able to finish the pending write and continue to write,
7428 // despite the paused HelloRequest.
7429 ASSERT_EQ(int(sizeof(kInput)),
7430 SSL_write(client.get(), kInput, sizeof(kInput)));
7431 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7432 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7433
7434 ASSERT_EQ(int(sizeof(kInput)),
7435 SSL_write(client.get(), kInput, sizeof(kInput)));
7436 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7437 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7438
7439 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7440 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7441 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7442
7443 ASSERT_TRUE(SSL_renegotiate(client.get()));
7444 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7445 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7446
7447 // We never renegotiate as a server.
7448 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7449 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7450 uint32_t err = ERR_get_error();
7451 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7452 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7453}
7454
David Benjamin10fef972022-08-30 11:38:51 -04007455TEST(SSLTest, ConnectionPropertiesDuringRenegotiate) {
7456 // Configure known connection properties, so we can check against them.
7457 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7458 ASSERT_TRUE(ctx);
7459 bssl::UniquePtr<X509> cert = GetTestCertificate();
7460 ASSERT_TRUE(cert);
7461 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7462 ASSERT_TRUE(key);
7463 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7464 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7465 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7466 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7467 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7468 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7469 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), "X25519"));
7470 ASSERT_TRUE(SSL_CTX_set1_sigalgs_list(ctx.get(), "rsa_pkcs1_sha256"));
7471
7472 // Connect a client and server that accept renegotiation.
7473 bssl::UniquePtr<SSL> client, server;
7474 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
7475 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7476 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7477
7478 auto check_properties = [&] {
7479 EXPECT_EQ(SSL_version(client.get()), TLS1_2_VERSION);
7480 const SSL_CIPHER *cipher = SSL_get_current_cipher(client.get());
7481 ASSERT_TRUE(cipher);
7482 EXPECT_EQ(SSL_CIPHER_get_id(cipher),
7483 uint32_t{TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256});
7484 EXPECT_EQ(SSL_get_curve_id(client.get()), SSL_CURVE_X25519);
7485 EXPECT_EQ(SSL_get_peer_signature_algorithm(client.get()),
7486 SSL_SIGN_RSA_PKCS1_SHA256);
7487 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
7488 ASSERT_TRUE(peer);
7489 EXPECT_EQ(X509_cmp(cert.get(), peer.get()), 0);
7490 };
7491 check_properties();
7492
7493 // The server sends a HelloRequest.
7494 ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
7495
7496 // Reading from the client will consume the HelloRequest, start a
7497 // renegotiation, and then block on a ServerHello from the server.
7498 uint8_t byte;
7499 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7500 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7501
7502 // Connection properties should continue to report values from the original
7503 // handshake.
7504 check_properties();
7505}
David Benjaminf9e0cda2020-03-23 18:29:09 -04007506
7507TEST(SSLTest, CopyWithoutEarlyData) {
7508 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007509 bssl::UniquePtr<SSL_CTX> server_ctx(
7510 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007511 ASSERT_TRUE(client_ctx);
7512 ASSERT_TRUE(server_ctx);
7513
David Benjaminf9e0cda2020-03-23 18:29:09 -04007514 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7515 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7516 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7517 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7518
7519 bssl::UniquePtr<SSL_SESSION> session =
7520 CreateClientSession(client_ctx.get(), server_ctx.get());
7521 ASSERT_TRUE(session);
7522
7523 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007524 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007525 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7526 server_ctx.get()));
7527 SSL_set_session(client.get(), session.get());
7528 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007529 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7530 EXPECT_TRUE(SSL_in_early_data(client.get()));
7531
7532 // |SSL_SESSION_copy_without_early_data| should disable early data but
7533 // still resume the session.
7534 bssl::UniquePtr<SSL_SESSION> session2(
7535 SSL_SESSION_copy_without_early_data(session.get()));
7536 ASSERT_TRUE(session2);
7537 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007538 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7539 server_ctx.get()));
7540 SSL_set_session(client.get(), session2.get());
7541 SSL_set_early_data_enabled(client.get(), 1);
7542 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007543 EXPECT_TRUE(SSL_session_reused(client.get()));
7544 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7545 SSL_get_early_data_reason(client.get()));
7546
7547 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7548 // when passed an early-data-incapable session.
7549 bssl::UniquePtr<SSL_SESSION> session3(
7550 SSL_SESSION_copy_without_early_data(session2.get()));
7551 EXPECT_EQ(session2.get(), session3.get());
7552}
7553
Adam Langley53a17f52020-05-26 14:44:07 -07007554TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7555 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007556 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007557 bssl::UniquePtr<SSL_CTX> server_ctx(
7558 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007559 ASSERT_TRUE(client_ctx);
7560 ASSERT_TRUE(server_ctx);
7561 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7562 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7563 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7564 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007565
7566 bssl::UniquePtr<SSL> client, server;
7567 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7568 server_ctx.get()));
7569 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7570
7571 // Process a TLS 1.3 NewSessionTicket.
7572 static const uint8_t kTicket[] = {
7573 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7574 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7575 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7576 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7577 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7578 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7579 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7580 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7581 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7582 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7583 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7584 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7585 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7586 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7587 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7588 0x00, 0x00,
7589 };
7590 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7591 client.get(), kTicket, sizeof(kTicket)));
7592 ASSERT_TRUE(session);
7593 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7594
7595 uint8_t *session_buf = nullptr;
7596 size_t session_length = 0;
7597 ASSERT_TRUE(
7598 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7599 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7600 ASSERT_TRUE(session_buf);
7601 ASSERT_GT(session_length, 0u);
7602
7603 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7604 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7605 sizeof(kTicket)));
7606
7607 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7608 // handshake completes.
7609 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7610 ASSERT_TRUE(client2);
7611 SSL_set_connect_state(client2.get());
7612 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7613 sizeof(kTicket)));
7614}
7615
David Benjamin3989c992020-10-09 14:12:06 -04007616TEST(SSLTest, BIO) {
7617 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007618 bssl::UniquePtr<SSL_CTX> server_ctx(
7619 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007620 ASSERT_TRUE(client_ctx);
7621 ASSERT_TRUE(server_ctx);
7622
David Benjamin3989c992020-10-09 14:12:06 -04007623 for (bool take_ownership : {true, false}) {
7624 // For simplicity, get the handshake out of the way first.
7625 bssl::UniquePtr<SSL> client, server;
7626 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7627 server_ctx.get()));
7628
7629 // Wrap |client| in an SSL BIO.
7630 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7631 ASSERT_TRUE(client_bio);
7632 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7633 if (take_ownership) {
7634 client.release();
7635 }
7636
7637 // Flushing the BIO should not crash.
7638 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7639
7640 // Exchange some data.
7641 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7642 uint8_t buf[5];
7643 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7644 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7645
7646 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7647 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7648 EXPECT_EQ(Bytes("world"), Bytes(buf));
7649
7650 // |BIO_should_read| should work.
7651 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7652 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7653
7654 // Writing data should eventually exceed the buffer size and fail, reporting
7655 // |BIO_should_write|.
7656 int ret;
7657 for (int i = 0; i < 1024; i++) {
7658 std::vector<uint8_t> buffer(1024);
7659 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7660 if (ret <= 0) {
7661 break;
7662 }
7663 }
7664 EXPECT_EQ(-1, ret);
7665 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7666 }
7667}
7668
David Benjamin12a3e7e2021-04-13 11:47:36 -04007669TEST(SSLTest, ALPNConfig) {
7670 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7671 ASSERT_TRUE(ctx);
7672 bssl::UniquePtr<X509> cert = GetTestCertificate();
7673 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7674 ASSERT_TRUE(cert);
7675 ASSERT_TRUE(key);
7676 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7677 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7678
7679 // Set up some machinery to check the configured ALPN against what is actually
7680 // sent over the wire. Note that the ALPN callback is only called when the
7681 // client offers ALPN.
7682 std::vector<uint8_t> observed_alpn;
7683 SSL_CTX_set_alpn_select_cb(
7684 ctx.get(),
7685 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7686 unsigned in_len, void *arg) -> int {
7687 std::vector<uint8_t> *observed_alpn_ptr =
7688 static_cast<std::vector<uint8_t> *>(arg);
7689 observed_alpn_ptr->assign(in, in + in_len);
7690 return SSL_TLSEXT_ERR_NOACK;
7691 },
7692 &observed_alpn);
7693 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7694 observed_alpn.clear();
7695 bssl::UniquePtr<SSL> client, server;
7696 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7697 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7698 };
7699
7700 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7701 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7702 0x03, 'b', 'a', 'r'};
7703 EXPECT_EQ(0,
7704 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7705 check_alpn_proto(kValidList);
7706
7707 // Invalid lists are rejected.
7708 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7709 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7710 sizeof(kInvalidList)));
7711
7712 // Empty lists are valid and are interpreted as disabling ALPN.
7713 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7714 check_alpn_proto({});
7715}
7716
David Benjamin2f3958a2021-04-16 11:55:23 -04007717// Test that the key usage checker can correctly handle issuerUID and
7718// subjectUID. See https://crbug.com/1199744.
7719TEST(SSLTest, KeyUsageWithUIDs) {
7720 static const char kGoodKeyUsage[] = R"(
7721-----BEGIN CERTIFICATE-----
7722MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7723AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7724aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7725CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7726ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
77274r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7728Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7729ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7730A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
773134EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
77324Z7qDhjIhiF4dM0uEDYRVA==
7733-----END CERTIFICATE-----
7734)";
7735 static const char kBadKeyUsage[] = R"(
7736-----BEGIN CERTIFICATE-----
7737MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7738AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7739aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7740CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7741ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
77424r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7743Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7744ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7745A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7746taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7747RHrQbWsFUakETXL9QMlegh5t
7748-----END CERTIFICATE-----
7749)";
7750
7751 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7752 ASSERT_TRUE(good);
7753 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7754 ASSERT_TRUE(bad);
7755
7756 // We check key usage when configuring EC certificates to distinguish ECDSA
7757 // and ECDH.
7758 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7759 ASSERT_TRUE(ctx);
7760 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7761 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7762}
7763
David Benjamin9b2cdb72021-04-01 23:21:53 -04007764// Test that |SSL_can_release_private_key| reports true as early as expected.
7765// The internal asserts in the library check we do not report true too early.
7766TEST(SSLTest, CanReleasePrivateKey) {
7767 bssl::UniquePtr<SSL_CTX> client_ctx =
7768 CreateContextWithTestCertificate(TLS_method());
7769 ASSERT_TRUE(client_ctx);
7770 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7771
7772 // Note this assumes the transport buffer is large enough to fit the client
7773 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7774 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7775 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7776 // Write the ClientHello.
7777 ASSERT_EQ(-1, SSL_do_handshake(client));
7778 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7779
7780 // Consume the ClientHello and write the server flight.
7781 ASSERT_EQ(-1, SSL_do_handshake(server));
7782 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7783
7784 EXPECT_TRUE(SSL_can_release_private_key(server));
7785 };
7786
7787 {
7788 SCOPED_TRACE("TLS 1.2 ECDHE");
7789 bssl::UniquePtr<SSL_CTX> server_ctx(
7790 CreateContextWithTestCertificate(TLS_method()));
7791 ASSERT_TRUE(server_ctx);
7792 ASSERT_TRUE(
7793 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7794 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7795 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7796 // Configure the server to request client certificates, so we can also test
7797 // the client half.
7798 SSL_CTX_set_custom_verify(
7799 server_ctx.get(), SSL_VERIFY_PEER,
7800 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7801 bssl::UniquePtr<SSL> client, server;
7802 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7803 server_ctx.get()));
7804 check_first_server_round_trip(client.get(), server.get());
7805
7806 // Consume the server flight and write the client response. The client still
7807 // has a Finished message to consume but can also release its key early.
7808 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7809 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7810 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7811
7812 // However, a client that has not disabled renegotiation can never release
7813 // the key.
7814 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7815 server_ctx.get()));
7816 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7817 check_first_server_round_trip(client.get(), server.get());
7818 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7819 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7820 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7821 }
7822
7823 {
7824 SCOPED_TRACE("TLS 1.2 resumption");
7825 bssl::UniquePtr<SSL_CTX> server_ctx(
7826 CreateContextWithTestCertificate(TLS_method()));
7827 ASSERT_TRUE(server_ctx);
7828 ASSERT_TRUE(
7829 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7830 bssl::UniquePtr<SSL_SESSION> session =
7831 CreateClientSession(client_ctx.get(), server_ctx.get());
7832 ASSERT_TRUE(session);
7833 bssl::UniquePtr<SSL> client, server;
7834 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7835 server_ctx.get()));
7836 SSL_set_session(client.get(), session.get());
7837 check_first_server_round_trip(client.get(), server.get());
7838 }
7839
7840 {
7841 SCOPED_TRACE("TLS 1.3 1-RTT");
7842 bssl::UniquePtr<SSL_CTX> server_ctx(
7843 CreateContextWithTestCertificate(TLS_method()));
7844 ASSERT_TRUE(server_ctx);
7845 ASSERT_TRUE(
7846 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7847 bssl::UniquePtr<SSL> client, server;
7848 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7849 server_ctx.get()));
7850 check_first_server_round_trip(client.get(), server.get());
7851 }
7852
7853 {
7854 SCOPED_TRACE("TLS 1.3 resumption");
7855 bssl::UniquePtr<SSL_CTX> server_ctx(
7856 CreateContextWithTestCertificate(TLS_method()));
7857 ASSERT_TRUE(server_ctx);
7858 ASSERT_TRUE(
7859 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7860 bssl::UniquePtr<SSL_SESSION> session =
7861 CreateClientSession(client_ctx.get(), server_ctx.get());
7862 ASSERT_TRUE(session);
7863 bssl::UniquePtr<SSL> client, server;
7864 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7865 server_ctx.get()));
7866 SSL_set_session(client.get(), session.get());
7867 check_first_server_round_trip(client.get(), server.get());
7868 }
7869}
7870
David Benjamine9c5d722021-06-09 17:43:16 -04007871// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7872// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7873// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7874// will be set to the ClientHelloInner's extensions, rather than
7875// ClientHelloOuter.
7876static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7877 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7878 struct AppData {
7879 std::vector<uint16_t> *out;
7880 bool decrypt_ech;
7881 bool callback_done = false;
7882 };
7883 AppData app_data;
7884 app_data.out = out;
7885 app_data.decrypt_ech = decrypt_ech;
7886
7887 bssl::UniquePtr<SSL_CTX> server_ctx =
7888 CreateContextWithTestCertificate(TLS_method());
7889 if (!server_ctx || //
7890 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7891 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7892 return false;
7893 }
7894
7895 // Configure the server to record the ClientHello extension order. We use a
7896 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7897 SSL_CTX_set_select_certificate_cb(
7898 server_ctx.get(),
7899 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7900 AppData *app_data_ptr = static_cast<AppData *>(
7901 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7902 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7903 SSL_ech_accepted(client_hello->ssl));
7904
7905 app_data_ptr->out->clear();
7906 CBS extensions;
7907 CBS_init(&extensions, client_hello->extensions,
7908 client_hello->extensions_len);
7909 while (CBS_len(&extensions)) {
7910 uint16_t type;
7911 CBS body;
7912 if (!CBS_get_u16(&extensions, &type) ||
7913 !CBS_get_u16_length_prefixed(&extensions, &body)) {
7914 return ssl_select_cert_error;
7915 }
7916 app_data_ptr->out->push_back(type);
7917 }
7918
7919 // Don't bother completing the handshake.
7920 app_data_ptr->callback_done = true;
7921 return ssl_select_cert_error;
7922 });
7923
7924 bssl::UniquePtr<SSL> client, server;
7925 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
7926 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
7927 return false;
7928 }
7929
7930 // Run the handshake far enough to process the ClientHello.
7931 SSL_do_handshake(client.get());
7932 SSL_do_handshake(server.get());
7933 return app_data.callback_done;
7934}
7935
7936// Test that, when extension permutation is enabled, the ClientHello extension
7937// order changes, both with and without ECH, and in both ClientHelloInner and
7938// ClientHelloOuter.
7939TEST(SSLTest, PermuteExtensions) {
7940 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
7941 ASSERT_TRUE(keys);
7942 for (bool offer_ech : {false, true}) {
7943 SCOPED_TRACE(offer_ech);
7944 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
7945 for (bool decrypt_ech : {false, true}) {
7946 SCOPED_TRACE(decrypt_ech);
7947 if (!offer_ech && decrypt_ech) {
7948 continue;
7949 }
7950
7951 // When extension permutation is disabled, the order should be consistent.
7952 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7953 ASSERT_TRUE(ctx);
7954 std::vector<uint16_t> order1, order2;
7955 ASSERT_TRUE(
7956 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7957 ASSERT_TRUE(
7958 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7959 EXPECT_EQ(order1, order2);
7960
7961 ctx.reset(SSL_CTX_new(TLS_method()));
7962 ASSERT_TRUE(ctx);
7963 SSL_CTX_set_permute_extensions(ctx.get(), 1);
7964
7965 // When extension permutation is enabled, each ClientHello should have a
7966 // different order.
7967 //
7968 // This test is inherently flaky, so we run it multiple times. We send at
7969 // least five extensions by default from TLS 1.3: supported_versions,
7970 // key_share, supported_groups, psk_key_exchange_modes, and
7971 // signature_algorithms. That means the probability of a false negative is
7972 // at most 1/120. Repeating the test 14 times lowers false negative rate
7973 // to under 2^-96.
7974 ASSERT_TRUE(
7975 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
7976 EXPECT_GE(order1.size(), 5u);
7977 static const int kNumIterations = 14;
7978 bool passed = false;
7979 for (int i = 0; i < kNumIterations; i++) {
7980 ASSERT_TRUE(
7981 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
7982 if (order1 != order2) {
7983 passed = true;
7984 break;
7985 }
7986 }
7987 EXPECT_TRUE(passed) << "Extensions were not permuted";
7988 }
7989 }
7990}
7991
Adam Langley7e7e6b62021-12-06 13:04:07 -08007992TEST(SSLTest, HostMatching) {
David Benjaminc3c540b2021-12-08 15:12:51 -05007993 static const char kCertPEM[] = R"(
7994-----BEGIN CERTIFICATE-----
7995MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw
7996DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2
7997MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD
7998VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO
7999Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW
8000ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr
8001BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3
8002Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP
8003YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD
8004AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu
80055DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY=
8006-----END CERTIFICATE-----
8007)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008008 bssl::UniquePtr<X509> cert(CertFromPEM(kCertPEM));
8009 ASSERT_TRUE(cert);
David Benjaminc3c540b2021-12-08 15:12:51 -05008010 static const char kCertNoSANsPEM[] = R"(
8011-----BEGIN CERTIFICATE-----
8012MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw
8013EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy
8014MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV
8015MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
8016u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw
8017L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG
8018CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG
8019SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW
8020pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4=
8021-----END CERTIFICATE-----
8022)";
8023 bssl::UniquePtr<X509> cert_no_sans(CertFromPEM(kCertNoSANsPEM));
8024 ASSERT_TRUE(cert_no_sans);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008025
David Benjaminc3c540b2021-12-08 15:12:51 -05008026 static const char kKeyPEM[] = R"(
8027-----BEGIN PRIVATE KEY-----
8028MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ
8029MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+
8030RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
8031-----END PRIVATE KEY-----
8032)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008033 bssl::UniquePtr<EVP_PKEY> key(KeyFromPEM(kKeyPEM));
8034 ASSERT_TRUE(key);
8035
Adam Langley7e7e6b62021-12-06 13:04:07 -08008036 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8037 ASSERT_TRUE(client_ctx);
8038 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8039 cert.get()));
David Benjaminc3c540b2021-12-08 15:12:51 -05008040 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8041 cert_no_sans.get()));
Adam Langley7e7e6b62021-12-06 13:04:07 -08008042 SSL_CTX_set_verify(client_ctx.get(),
8043 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
8044 nullptr);
Bob Beck1ccef492022-12-06 16:07:05 -07008045 X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
8046 X509_V_FLAG_NO_CHECK_TIME);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008047
8048 struct TestCase {
David Benjaminc3c540b2021-12-08 15:12:51 -05008049 X509 *cert;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008050 std::string hostname;
8051 unsigned flags;
8052 bool should_match;
8053 };
8054 std::vector<TestCase> kTests = {
8055 // These two names are present as SANs in the certificate.
David Benjaminc3c540b2021-12-08 15:12:51 -05008056 {cert.get(), "example1.com", 0, true},
8057 {cert.get(), "example2.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008058 // This is the CN of the certificate, but that shouldn't matter if a SAN
8059 // extension is present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008060 {cert.get(), "example3.com", 0, false},
8061 // If the SAN is not present, we, for now, look for DNS names in the CN.
8062 {cert_no_sans.get(), "example3.com", 0, true},
8063 // ... but this can be turned off.
8064 {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT,
8065 false},
8066 // a*.example4.com is a SAN, but is invalid.
8067 {cert.get(), "abc.example4.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008068 // *.example5.com is a SAN in the certificate, which is a normal and valid
8069 // wildcard.
David Benjaminc3c540b2021-12-08 15:12:51 -05008070 {cert.get(), "abc.example5.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008071 // This name is not present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008072 {cert.get(), "notexample1.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008073 // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a
8074 // hostname that happens to be its textual representation.
David Benjaminc3c540b2021-12-08 15:12:51 -05008075 {cert.get(), "1.2.3.4", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008076 };
8077
Adam Langley7e7e6b62021-12-06 13:04:07 -08008078 for (const TestCase &test : kTests) {
8079 SCOPED_TRACE(test.hostname);
David Benjaminc3c540b2021-12-08 15:12:51 -05008080
8081 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8082 ASSERT_TRUE(server_ctx);
8083 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert));
8084 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8085
8086 ClientConfig config;
8087 bssl::UniquePtr<SSL> client, server;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008088 config.verify_hostname = test.hostname;
8089 config.hostflags = test.flags;
8090 EXPECT_EQ(test.should_match,
8091 ConnectClientAndServer(&client, &server, client_ctx.get(),
8092 server_ctx.get(), config));
8093 }
8094}
8095
David Benjamin3f180b82022-05-09 17:45:18 -04008096TEST(SSLTest, NumTickets) {
8097 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8098 ASSERT_TRUE(server_ctx);
8099 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8100 ASSERT_TRUE(client_ctx);
8101 bssl::UniquePtr<X509> cert = GetTestCertificate();
8102 ASSERT_TRUE(cert);
8103 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8104 ASSERT_TRUE(key);
8105 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
8106 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8107 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8108
8109 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8110 static size_t ticket_count;
8111 SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int {
8112 ticket_count++;
8113 return 0;
8114 });
8115
8116 auto count_tickets = [&]() -> size_t {
8117 ticket_count = 0;
8118 bssl::UniquePtr<SSL> client, server;
8119 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
8120 server_ctx.get()) ||
8121 !FlushNewSessionTickets(client.get(), server.get())) {
8122 ADD_FAILURE() << "Could not run handshake";
8123 return 0;
8124 }
8125 return ticket_count;
8126 };
8127
8128 // By default, we should send two tickets.
8129 EXPECT_EQ(count_tickets(), 2u);
8130
8131 for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) {
8132 SCOPED_TRACE(num_tickets);
8133 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets));
David Benjamin5697a922022-07-21 10:35:59 -07008134 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), num_tickets);
David Benjamin3f180b82022-05-09 17:45:18 -04008135 EXPECT_EQ(count_tickets(), num_tickets);
8136 }
8137
8138 // Configuring too many tickets causes us to stop at some point.
8139 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000));
David Benjamin5697a922022-07-21 10:35:59 -07008140 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), 16u);
David Benjamin3f180b82022-05-09 17:45:18 -04008141 EXPECT_EQ(count_tickets(), 16u);
8142}
8143
David Benjamin955ef792022-06-13 13:16:43 -04008144TEST(SSLTest, CertSubjectsToStack) {
8145 const std::string kCert1 = R"(
8146-----BEGIN CERTIFICATE-----
8147MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
8148QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
8149dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
8150BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
8151dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
8152v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
8153HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
8154HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
8155BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
8156BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
8157-----END CERTIFICATE-----
8158)";
8159 const std::vector<uint8_t> kName1 = {
8160 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
8161 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
8162 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
8163 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
8164 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
8165 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
8166 const std::string kCert2 = R"(
8167-----BEGIN CERTIFICATE-----
8168MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE
8169ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg
8170Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y
8171aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3
8172DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c
8173oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j
81745x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh
8175TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
8176CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0
81774nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB
8178gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y
8179rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU
8180xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==
8181-----END CERTIFICATE-----
8182)";
8183 const std::vector<uint8_t> kName2 = {
8184 0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a,
8185 0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c,
8186 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30,
8187 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61,
8188 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
8189
8190 const struct {
8191 std::vector<std::vector<uint8_t>> existing;
8192 std::string pem;
8193 std::vector<std::vector<uint8_t>> expected;
8194 } kTests[] = {
8195 // Do nothing.
8196 {{}, "", {}},
8197 // Append to an empty list, skipping duplicates.
8198 {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}},
8199 // One of the names was already present.
8200 {{kName1}, kCert1 + kCert2, {kName1, kName2}},
8201 // Both names were already present.
8202 {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}},
8203 // Preserve existing duplicates.
8204 {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}},
8205 };
8206 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
8207 SCOPED_TRACE(i);
8208 const auto &t = kTests[i];
8209
8210 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
8211 ASSERT_TRUE(stack);
8212 for (const auto& name : t.existing) {
8213 const uint8_t *inp = name.data();
8214 bssl::UniquePtr<X509_NAME> name_obj(
8215 d2i_X509_NAME(nullptr, &inp, name.size()));
8216 ASSERT_TRUE(name_obj);
8217 EXPECT_EQ(inp, name.data() + name.size());
8218 ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj)));
8219 }
8220
8221 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(t.pem.data(), t.pem.size()));
8222 ASSERT_TRUE(bio);
8223 ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get()));
8224
8225 // The function should have left |stack|'s comparison function alone.
8226 EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr));
8227
8228 std::vector<std::vector<uint8_t>> expected = t.expected, result;
8229 for (X509_NAME *name : stack.get()) {
8230 uint8_t *der = nullptr;
8231 int der_len = i2d_X509_NAME(name, &der);
8232 ASSERT_GE(der_len, 0);
8233 result.push_back(std::vector<uint8_t>(der, der + der_len));
8234 OPENSSL_free(der);
8235 }
8236
8237 // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a
8238 // well-defined order.
8239 std::sort(expected.begin(), expected.end());
8240 std::sort(result.begin(), result.end());
8241 EXPECT_EQ(result, expected);
8242 }
8243}
8244
David Benjamin4da5a942022-08-02 14:39:44 -07008245#if defined(OPENSSL_LINUX) || defined(OPENSSL_APPLE)
8246TEST(SSLTest, EmptyClientCAList) {
8247 // Use /dev/null on POSIX systems as an empty file.
8248 bssl::UniquePtr<STACK_OF(X509_NAME)> names(
8249 SSL_load_client_CA_file("/dev/null"));
8250 EXPECT_FALSE(names);
8251}
8252#endif // OPENSSL_LINUX || OPENSSL_APPLE
8253
David Benjaminb95c7e52022-07-22 16:28:22 -07008254TEST(SSLTest, EmptyWriteBlockedOnHandshakeData) {
8255 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8256 bssl::UniquePtr<SSL_CTX> server_ctx =
8257 CreateContextWithTestCertificate(TLS_method());
8258 ASSERT_TRUE(client_ctx);
8259 ASSERT_TRUE(server_ctx);
8260 // Configure only TLS 1.3. This test requires post-handshake NewSessionTicket.
8261 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
8262 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
8263
8264 // Connect a client and server with tiny buffer between the two.
8265 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
8266 server(SSL_new(server_ctx.get()));
8267 ASSERT_TRUE(client);
8268 ASSERT_TRUE(server);
8269 SSL_set_connect_state(client.get());
8270 SSL_set_accept_state(server.get());
8271 BIO *bio1, *bio2;
8272 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
8273 SSL_set_bio(client.get(), bio1, bio1);
8274 SSL_set_bio(server.get(), bio2, bio2);
8275 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
8276
8277 // We defer NewSessionTicket to the first write, so the server has a pending
8278 // NewSessionTicket. See https://boringssl-review.googlesource.com/34948. This
8279 // means an empty write will flush the ticket. However, the transport only
8280 // allows one byte through, so this will fail with |SSL_ERROR_WANT_WRITE|.
8281 int ret = SSL_write(server.get(), nullptr, 0);
8282 ASSERT_EQ(ret, -1);
8283 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8284
8285 // Attempting to write non-zero data should not trip |SSL_R_BAD_WRITE_RETRY|.
8286 const uint8_t kData[] = {'h', 'e', 'l', 'l', 'o'};
8287 ret = SSL_write(server.get(), kData, sizeof(kData));
8288 ASSERT_EQ(ret, -1);
8289 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8290
8291 // Byte by byte, the data should eventually get through.
8292 uint8_t buf[sizeof(kData)];
8293 for (;;) {
8294 ret = SSL_read(client.get(), buf, sizeof(buf));
8295 ASSERT_EQ(ret, -1);
8296 ASSERT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ);
8297
8298 ret = SSL_write(server.get(), kData, sizeof(kData));
8299 if (ret > 0) {
8300 ASSERT_EQ(ret, 5);
8301 break;
8302 }
8303 ASSERT_EQ(ret, -1);
8304 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8305 }
8306
8307 ret = SSL_read(client.get(), buf, sizeof(buf));
8308 ASSERT_EQ(ret, static_cast<int>(sizeof(kData)));
8309 ASSERT_EQ(Bytes(buf, ret), Bytes(kData));
8310}
8311
David Benjamin5cb597e2022-07-27 18:34:39 -07008312// Test that |SSL_ERROR_SYSCALL| continues to work after a close_notify.
8313TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
8314 // Make a custom |BIO| where writes fail, but without pushing to the error
8315 // queue.
8316 bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
8317 ASSERT_TRUE(method);
8318 BIO_meth_set_create(method.get(), [](BIO *b) -> int {
8319 BIO_set_init(b, 1);
8320 return 1;
8321 });
8322 static bool write_failed = false;
8323 BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
8324 // Fail the operation and don't add to the error queue.
8325 write_failed = true;
8326 return -1;
8327 });
8328 bssl::UniquePtr<BIO> wbio_silent_error(BIO_new(method.get()));
8329 ASSERT_TRUE(wbio_silent_error);
8330
8331 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8332 bssl::UniquePtr<SSL_CTX> server_ctx =
8333 CreateContextWithTestCertificate(TLS_method());
8334 ASSERT_TRUE(client_ctx);
8335 ASSERT_TRUE(server_ctx);
8336 bssl::UniquePtr<SSL> client, server;
8337 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8338 server_ctx.get()));
8339
8340 // Replace the write |BIO| with |wbio_silent_error|.
8341 SSL_set0_wbio(client.get(), wbio_silent_error.release());
8342
8343 // Writes should fail. There is nothing in the error queue, so
8344 // |SSL_ERROR_SYSCALL| indicates the caller needs to check out-of-band.
8345 const uint8_t data[1] = {0};
8346 int ret = SSL_write(client.get(), data, sizeof(data));
8347 EXPECT_EQ(ret, -1);
8348 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8349 EXPECT_TRUE(write_failed);
8350 write_failed = false;
8351
8352 // Send a close_notify from the server. It should return 0 because
8353 // close_notify was sent, but not received. Confusingly, this is a success
8354 // output for |SSL_shutdown|'s API.
8355 EXPECT_EQ(SSL_shutdown(server.get()), 0);
8356
8357 // Read the close_notify on the client.
8358 uint8_t buf[1];
8359 ret = SSL_read(client.get(), buf, sizeof(buf));
8360 EXPECT_EQ(ret, 0);
8361 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
8362
David Benjaminebd8b892022-07-27 18:41:51 -07008363 // Further calls to |SSL_read| continue to report |SSL_ERROR_ZERO_RETURN|.
8364 ret = SSL_read(client.get(), buf, sizeof(buf));
8365 EXPECT_EQ(ret, 0);
8366 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
8367
David Benjamin5cb597e2022-07-27 18:34:39 -07008368 // Although the client has seen close_notify, it should continue to report
8369 // |SSL_ERROR_SYSCALL| when its writes fail.
8370 ret = SSL_write(client.get(), data, sizeof(data));
8371 EXPECT_EQ(ret, -1);
8372 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8373 EXPECT_TRUE(write_failed);
8374 write_failed = false;
David Benjaminebd8b892022-07-27 18:41:51 -07008375
8376 // Cause |BIO_write| to fail with a return value of zero instead.
8377 // |SSL_get_error| should not misinterpret this as a close_notify.
8378 //
8379 // This is not actually a correct implementation of |BIO_write|, but the rest
8380 // of the code treats zero from |BIO_write| as an error, so ensure it does so
8381 // correctly. Fixing https://crbug.com/boringssl/503 will make this case moot.
8382 BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
8383 write_failed = true;
8384 return 0;
8385 });
8386 ret = SSL_write(client.get(), data, sizeof(data));
8387 EXPECT_EQ(ret, 0);
8388 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8389 EXPECT_TRUE(write_failed);
8390 write_failed = false;
David Benjamin5cb597e2022-07-27 18:34:39 -07008391}
8392
David Benjamin401137f2022-07-28 10:27:47 -07008393// Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving
8394// a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|.
8395TEST(SSLTest, QuietShutdown) {
8396 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8397 bssl::UniquePtr<SSL_CTX> server_ctx =
8398 CreateContextWithTestCertificate(TLS_method());
8399 ASSERT_TRUE(client_ctx);
8400 ASSERT_TRUE(server_ctx);
8401 SSL_CTX_set_quiet_shutdown(server_ctx.get(), 1);
8402 bssl::UniquePtr<SSL> client, server;
8403 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8404 server_ctx.get()));
8405
8406 // Quiet shutdown is enabled, so |SSL_shutdown| on the server should
8407 // immediately return that bidirectional shutdown "completed".
8408 EXPECT_EQ(SSL_shutdown(server.get()), 1);
8409
8410 // Shut down writes so the client gets an EOF.
8411 EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(server.get())));
8412
8413 // Confirm no close notify was actually sent. Client reads should report a
8414 // transport EOF, not a close_notify. (Both have zero return, but
8415 // |SSL_get_error| is different.)
8416 char buf[1];
8417 int ret = SSL_read(client.get(), buf, sizeof(buf));
8418 EXPECT_EQ(ret, 0);
8419 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8420
8421 // The server believes bidirectional shutdown completed, so reads should
8422 // replay the (simulated) close_notify.
8423 ret = SSL_read(server.get(), buf, sizeof(buf));
8424 EXPECT_EQ(ret, 0);
8425 EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_ZERO_RETURN);
8426}
8427
Martin Kreichgauer72912d22017-08-04 12:06:43 -07008428} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07008429BSSL_NAMESPACE_END